Deprecated old uartns550_v3_2 created new uartns550_v3_3

Signed-off-by: naga sureshkumar relli <nagasure@xilinx.com>
This commit is contained in:
naga sureshkumar relli 2015-04-13 17:48:24 +05:30 committed by Nava kishore Manne
parent daedbcdf08
commit bc3c5274cf
24 changed files with 5755 additions and 0 deletions

View file

@ -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

View file

@ -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
}

View file

@ -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

View file

@ -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

View file

@ -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
}

View file

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

View file

@ -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:
* <pre>
* 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.
* </pre>
******************************************************************************/
/***************************** 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_<UARTNS550_instance>_DEVICE_ID value from
* xparameters.h
*
* @return
* - XST_FAILURE if the UART driver could not be initialized
* successfully.
* - A non-negative number indicating the number of characters
* sent.
*
* @note None.
*
****************************************************************************/
int UartNs550HelloWorldExample(u16 DeviceId)
{
u8 HelloWorld[] = "Hello World";
int SentCount = 0;
int Status;
/*
* Initialize the UartNs550 device so that it is ready to use
*/
Status = XUartNs550_Initialize(&UartNs550, DeviceId);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
while (SentCount < sizeof(HelloWorld)) {
/*
* Transmit the data
*/
SentCount += XUartNs550_Send(&UartNs550,
&HelloWorld[SentCount], 1);
}
return SentCount;
}

View file

@ -0,0 +1,552 @@
/******************************************************************************
*
* 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_example.c
*
* This file contains a design example using the UART 16450/16550 driver
* (XUartNs550) and hardware device using interrupt mode.
*
* @note
*
* <pre>
* 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.
* </pre>
******************************************************************************/
/***************************** Include Files **********************************/
#include "xparameters.h"
#include "xuartns550.h"
#include "xil_exception.h"
#ifdef XPAR_INTC_0_DEVICE_ID
#include "xintc.h"
#include <stdio.h>
#else
#include "xscugic.h"
#include "xil_printf.h"
#endif
/************************** 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
#define UART_IRPT_INTR XPAR_INTC_0_UARTNS550_0_VEC_ID
#ifdef XPAR_INTC_0_DEVICE_ID
#define INTC_DEVICE_ID XPAR_INTC_0_DEVICE_ID
#else
#define INTC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID
#endif /* XPAR_INTC_0_DEVICE_ID */
#endif /* TESTAPP_GEN */
/*
* The following constant controls the length of the buffers to be sent
* and received with the UART.
*/
#define TEST_BUFFER_SIZE 100
/**************************** Type Definitions ********************************/
#ifdef XPAR_INTC_0_DEVICE_ID
#define INTC XIntc
#define INTC_HANDLER XIntc_InterruptHandler
#else
#define INTC XScuGic
#define INTC_HANDLER XScuGic_InterruptHandler
#endif /* XPAR_INTC_0_DEVICE_ID */
/************************** Function Prototypes *******************************/
int UartNs550IntrExample(INTC *IntcInstancePtr,
XUartNs550 *UartInstancePtr,
u16 UartDeviceId,
u16 UartIntrId);
void UartNs550IntrHandler(void *CallBackRef, u32 Event, unsigned int EventData);
static int UartNs550SetupIntrSystem(INTC *IntcInstancePtr,
XUartNs550 *UartInstancePtr,
u16 UartIntrId);
static void UartNs550DisableIntrSystem(INTC *IntcInstancePtr, u16 UartIntrId);
/************************** Variable Definitions ******************************/
#ifndef TESTAPP_GEN
XUartNs550 UartNs550Instance; /* Instance of the UART Device */
INTC IntcInstance; /* Instance of the Interrupt Controller */
#endif
/*
* 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 */
/*
* The following counters are used to determine when the entire buffer has
* been sent and received.
*/
static volatile int TotalReceivedCount;
static volatile int TotalSentCount;
static volatile int TotalErrorCount;
/******************************************************************************/
/**
*
* Main function to call the UartNs550 interrupt example.
*
* @param None.
*
* @return XST_SUCCESS if successful, otherwise XST_FAILURE.
*
* @note None.
*
*******************************************************************************/
#ifndef TESTAPP_GEN
int main(void)
{
int Status;
/*
* Run the UartNs550 Interrupt example.
*/
Status = UartNs550IntrExample(&IntcInstance,
&UartNs550Instance,
UART_DEVICE_ID,
UART_IRPT_INTR);
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.
*
* This function transmits data and expects to receive the same data through the
* UART using the local loopback of the hardware.
*
* This function uses interrupt driver mode of the UART.
*
* @param IntcInstancePtr is a pointer to the instance of the
* Interrupt Controller.
* @param UartInstancePtr is a pointer to the instance of the UART .
* @param UartDeviceId is the device Id and is typically
* XPAR_<UARTNS550_instance>_DEVICE_ID value from xparameters.h.
* @param UartIntrId is the interrupt Id and is typically
* XPAR_<INTC_instance>_<UARTNS550_instance>_IP2INTC_IRPT_INTR
* value from xparameters.h.
*
* @return XST_SUCCESS if successful, otherwise XST_FAILURE.
*
* @note
*
* This function contains an infinite loop such that if interrupts are not
* working it may never return.
*
*******************************************************************************/
int UartNs550IntrExample(INTC *IntcInstancePtr,
XUartNs550 *UartInstancePtr,
u16 UartDeviceId,
u16 UartIntrId)
{
int Status;
u32 Index;
u16 Options;
u32 BadByteCount = 0;
/*
* Initialize the UART driver so that it's ready to use.
*/
Status = XUartNs550_Initialize(UartInstancePtr, UartDeviceId);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Perform a self-test to ensure that the hardware was built correctly.
*/
Status = XUartNs550_SelfTest(UartInstancePtr);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Connect the UART to the interrupt subsystem such that interrupts can
* occur. This function is application specific.
*/
Status = UartNs550SetupIntrSystem(IntcInstancePtr,
UartInstancePtr,
UartIntrId);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Setup the handlers for the UART that will be called from the
* interrupt context when data has been sent and received, specify a
* pointer to the UART driver instance as the callback reference so
* the handlers are able to access the instance data.
*/
XUartNs550_SetHandler(UartInstancePtr, UartNs550IntrHandler,
UartInstancePtr);
/*
* Enable the interrupt of the UART so interrupts will occur, setup
* a local loopback so data that is sent will be received, and keep the
* FIFOs enabled.
*/
Options = XUN_OPTION_DATA_INTR | XUN_OPTION_LOOPBACK |
XUN_OPTION_FIFOS_ENABLE;
XUartNs550_SetOptions(UartInstancePtr, Options);
/*
* Initialize the send buffer bytes with a pattern to send and the
* the receive buffer bytes to zero to allow the receive data to be
* verified.
*/
for (Index = 0; Index < TEST_BUFFER_SIZE; Index++) {
SendBuffer[Index] = Index + 'A';
RecvBuffer[Index] = 0;
}
/*
* Start receiving data before sending it since there is a loopback,
* ignoring the number of bytes received as the return value since we
* know it will be zero and we are using interrupt mode.
*/
XUartNs550_Recv(UartInstancePtr, RecvBuffer, TEST_BUFFER_SIZE);
/*
* Send the buffer using the UART and ignore the number of bytes sent
* as the return value since we are using it in interrupt mode.
*/
XUartNs550_Send(UartInstancePtr, SendBuffer, TEST_BUFFER_SIZE);
/*
* Wait for the entire buffer to be received, letting the interrupt
* processing work in the background, this function may get locked
* up in this loop if the interrupts are not working correctly.
*/
while ((TotalReceivedCount != TEST_BUFFER_SIZE) ||
(TotalSentCount != TEST_BUFFER_SIZE)) {
}
/*
* Verify the entire receive buffer was successfully received.
*/
for (Index = 0; Index < TEST_BUFFER_SIZE; Index++) {
if (RecvBuffer[Index] != SendBuffer[Index]) {
BadByteCount++;
}
}
/*
* Disable the UartNs550 interrupt.
*/
UartNs550DisableIntrSystem(IntcInstancePtr, UartIntrId);
/*
* If any bytes were not correct, return an error.
*/
if (BadByteCount != 0) {
return XST_FAILURE;
}
/* Clear the counters */
TotalErrorCount = 0;
TotalReceivedCount = 0;
TotalSentCount = 0;
return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* This function is the handler which performs processing to handle data events
* from the UartNs550. It is called from an interrupt context such that the
* amount of processing performed should be minimized.
*
* This handler provides an example of how to handle data for the UART and
* is application specific.
*
* @param CallBackRef contains a callback reference from the driver,
* in thiscase it is the instance pointer for the UART driver.
* @param Event contains the specific kind of event that has occurred.
* @param EventData contains the number of bytes sent or received for sent
* and receive events.
*
* @return None.
*
* @note None.
*
*******************************************************************************/
void UartNs550IntrHandler(void *CallBackRef, u32 Event, unsigned int EventData)
{
u8 Errors;
XUartNs550 *UartNs550Ptr = (XUartNs550 *)CallBackRef;
/*
* All of the data has been sent.
*/
if (Event == XUN_EVENT_SENT_DATA) {
TotalSentCount = EventData;
}
/*
* All of the data has been received.
*/
if (Event == XUN_EVENT_RECV_DATA) {
TotalReceivedCount = EventData;
}
/*
* Data was received, but not the expected number of bytes, a
* timeout just indicates the data stopped for 4 character times.
*/
if (Event == XUN_EVENT_RECV_TIMEOUT) {
TotalReceivedCount = EventData;
}
/*
* Data was received with an error, keep the data but determine
* what kind of errors occurred.
*/
if (Event == XUN_EVENT_RECV_ERROR) {
TotalReceivedCount = EventData;
TotalErrorCount++;
Errors = XUartNs550_GetLastErrors(UartNs550Ptr);
}
}
/******************************************************************************/
/**
*
* This function setups the interrupt system such that interrupts can occur
* for the UART. This function is application specific since the actual
* system may or may not have an interrupt controller. The UART could be
* directly connected to a processor without an interrupt controller. The
* user should modify this function to fit the application.
*
* @param IntcInstancePtr is a pointer to the instance of the Interrupt
* Controller.
* @param UartInstancePtr is a pointer to the instance of the UART.
* @param UartIntrId is the interrupt Id and is typically
* XPAR_<INTC_instance>_<UARTNS550_instance>_VEC_ID value from
* xparameters.h.
*
* @return XST_SUCCESS if successful, otherwise XST_FAILURE.
*
* @note None.
*
*******************************************************************************/
static int UartNs550SetupIntrSystem(INTC *IntcInstancePtr,
XUartNs550 *UartInstancePtr,
u16 UartIntrId)
{
int Status;
#ifdef XPAR_INTC_0_DEVICE_ID
#ifndef TESTAPP_GEN
/*
* Initialize the interrupt controller driver so that it is ready
* to use.
*/
Status = XIntc_Initialize(IntcInstancePtr, INTC_DEVICE_ID);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
#endif /* TESTAPP_GEN */
/*
* Connect a device driver handler that will be called when an interrupt
* for the device occurs, the device driver handler performs the
* specific interrupt processing for the device.
*/
Status = XIntc_Connect(IntcInstancePtr, UartIntrId,
(XInterruptHandler)XUartNs550_InterruptHandler,
(void *)UartInstancePtr);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
#ifndef TESTAPP_GEN
/*
* Start the interrupt controller such that interrupts are enabled for
* all devices that cause interrupts, specific real mode so that
* the UART can cause interrupts thru the interrupt controller.
*/
Status = XIntc_Start(IntcInstancePtr, XIN_REAL_MODE);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
#endif /* TESTAPP_GEN */
/*
* Enable the interrupt for the UartNs550.
*/
XIntc_Enable(IntcInstancePtr, UartIntrId);
#else
#ifndef TESTAPP_GEN
XScuGic_Config *IntcConfig;
/*
* Initialize the interrupt controller driver so that it is ready to
* use.
*/
IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
if (NULL == IntcConfig) {
return XST_FAILURE;
}
Status = XScuGic_CfgInitialize(IntcInstancePtr, IntcConfig,
IntcConfig->CpuBaseAddress);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
#endif /* TESTAPP_GEN */
XScuGic_SetPriorityTriggerType(IntcInstancePtr, UartIntrId,
0xA0, 0x3);
/*
* Connect the interrupt handler that will be called when an
* interrupt occurs for the device.
*/
Status = XScuGic_Connect(IntcInstancePtr, UartIntrId,
(Xil_ExceptionHandler)XUartNs550_InterruptHandler,
UartInstancePtr);
if (Status != XST_SUCCESS) {
return Status;
}
/*
* Enable the interrupt for the Timer device.
*/
XScuGic_Enable(IntcInstancePtr, UartIntrId);
#endif /* XPAR_INTC_0_DEVICE_ID */
#ifndef TESTAPP_GEN
/*
* Initialize the exception table.
*/
Xil_ExceptionInit();
/*
* Register the interrupt controller handler with the exception table.
*/
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
(Xil_ExceptionHandler)INTC_HANDLER,
IntcInstancePtr);
/*
* Enable exceptions.
*/
Xil_ExceptionEnable();
#endif /* TESTAPP_GEN */
return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* This function disables the interrupts that occur for the UartNs550 device.
*
* @param IntcInstancePtr is the pointer to the instance of the Interrupt
* Controller.
* @param UartIntrId is the interrupt Id and is typically
* XPAR_<INTC_instance>_<UARTNS550_instance>_VEC_ID
* value from xparameters.h.
*
* @return None.
*
* @note None.
*
******************************************************************************/
static void UartNs550DisableIntrSystem(INTC *IntcInstancePtr, u16 UartIntrId)
{
/*
* Disconnect and disable the interrupt for the UartNs550 device.
*/
#ifdef XPAR_INTC_0_DEVICE_ID
XIntc_Disconnect(IntcInstancePtr, UartIntrId);
#else
XScuGic_Disable(IntcInstancePtr, UartIntrId);
XScuGic_Disconnect(IntcInstancePtr, UartIntrId);
#endif
}

View file

@ -0,0 +1,193 @@
/******************************************************************************
*
* 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_low_level_example.c
*
* This file contains a design example using the low-level driver functions
* and macros of the UART NS550 driver.
*
* @note None.
*
* MODIFICATION HISTORY:
* <pre>
* 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.
* </pre>
******************************************************************************/
/***************************** 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_<UARTNS550_instance>_BASEADDR value from
* xparameters.h.
*
* @return XST_SUCCESS if successful, XST_FAILURE if unsuccessful.
*
* @note None.
*
****************************************************************************/
int XUartNs550_LowLevelExample(u32 UartBaseAddress)
{
int Index;
/*
* Initialize the send buffer bytes with a pattern to send and the
* the receive buffer bytes to zero
*/
for (Index = 0; Index < TEST_BUFFER_SIZE; Index++) {
SendBuffer[Index] = Index + '0';
RecvBuffer[Index] = 0;
}
/*
* Set the baud rate and number of stop bits
*/
XUartNs550_SetBaud(UartBaseAddress, UART_CLOCK_HZ, UART_BAUDRATE);
XUartNs550_SetLineControlReg(UartBaseAddress, XUN_LCR_8_DATA_BITS);
/*
* Enable the FIFOs for 16550 mode since the defaults is NO FIFOs
*/
XUartNs550_WriteReg(UartBaseAddress, XUN_FCR_OFFSET, XUN_FIFO_ENABLE);
/*
* Send the entire transmit buffer
*/
for (Index = 0; Index < TEST_BUFFER_SIZE; Index++) {
XUartNs550_SendByte(UartBaseAddress, SendBuffer[Index]);
}
/*
* Receive the entire buffer's worth. Note that the RecvByte function
* blocks waiting for a character
*/
for (Index = 0; Index < TEST_BUFFER_SIZE; Index++) {
RecvBuffer[Index] = XUartNs550_RecvByte(UartBaseAddress);
}
/*
* Check the receive buffer data against the send buffer and verify the
* data was correctly received
*/
for (Index = 0; Index < TEST_BUFFER_SIZE; Index++) {
if (SendBuffer[Index] != RecvBuffer[Index]) {
return XST_FAILURE;
}
}
return XST_SUCCESS;
}

View file

@ -0,0 +1,237 @@
/******************************************************************************
*
* 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_polled_example.c
*
* This file contains a design example using the Uart 16450/550 driver
* (XUartNs550) and hardware device using polled mode.
*
* MODIFICATION HISTORY:
* <pre>
* 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
* </pre>
******************************************************************************/
/***************************** 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_<uartns550_instance>_DEVICE_ID value from
* xparameters.h.
*
* @return XST_SUCCESS if successful, XST_FAILURE if unsuccessful.
*
* @note This function polls the UART such that it may be not return
* if the hardware is not working correctly.
*
****************************************************************************/
int UartNs550PolledExample(u16 DeviceId)
{
int Status;
unsigned int SentCount;
unsigned int ReceivedCount = 0;
u16 Index;
u16 Options;
/*
* Initialize the UART Lite driver so that it's ready to use,
* specify the device ID that is generated in xparameters.h
*/
Status = XUartNs550_Initialize(&UartNs550, DeviceId);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Perform a self-test to ensure that the hardware was built correctly
*/
Status = XUartNs550_SelfTest(&UartNs550);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Enable the local loopback so data that is sent will be received,
* and keep the FIFOs enabled
*/
Options = XUN_OPTION_LOOPBACK | XUN_OPTION_FIFOS_ENABLE;
XUartNs550_SetOptions(&UartNs550, Options);
/*
* Initialize the send buffer bytes with a pattern to send and the
* the receive buffer bytes to zero
*/
for (Index = 0; Index < TEST_BUFFER_SIZE; Index++) {
SendBuffer[Index] = '0' + Index;
RecvBuffer[Index] = 0;
}
/*
* Send the buffer thru the UART waiting till the data can be
* sent (block), if the specified number of bytes was not sent
* successfully, then an error occurred
*/
SentCount = XUartNs550_Send(&UartNs550, SendBuffer, TEST_BUFFER_SIZE);
if (SentCount != TEST_BUFFER_SIZE) {
return XST_FAILURE;
}
/*
* Receive the number of bytes which is transfered.
* Data may be received in fifo with some delay hence we continuously
* check the receive fifo for valid data and update the receive buffer
* accordingly.
*/
while (1) {
ReceivedCount += XUartNs550_Recv(&UartNs550,
RecvBuffer + ReceivedCount,
TEST_BUFFER_SIZE - ReceivedCount);
if (ReceivedCount == TEST_BUFFER_SIZE)
{
break;
}
}
/*
* Check the receive buffer data against the send buffer and verify the
* data was correctly received
*/
for (Index = 0; Index < TEST_BUFFER_SIZE; Index++) {
if (SendBuffer[Index] != RecvBuffer[Index]) {
return XST_FAILURE;
}
}
/*
* Clean up the options
*/
Options = XUartNs550_GetOptions(&UartNs550);
Options = Options & ~(XUN_OPTION_LOOPBACK | XUN_OPTION_FIFOS_ENABLE);
XUartNs550_SetOptions(&UartNs550, Options);
return XST_SUCCESS;
}

View file

@ -0,0 +1,152 @@
/******************************************************************************
*
* 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_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:
* <pre>
* 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.
* </pre>
******************************************************************************/
/***************************** 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_<uartns550_instance>_DEVICE_ID value from
* xparameters.h.
*
* @return XST_SUCCESS if succesful, otherwise XST_FAILURE.
*
* @note None.
*
****************************************************************************/
int UartNs550SelfTestExample(u16 DeviceId)
{
int Status;
/*
* Initialize the UartNs550 driver so that it's ready to use
*/
Status = XUartNs550_Initialize(&UartNs550, DeviceId);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Perform a self-test to ensure that the hardware was built correctly
*/
Status = XUartNs550_SelfTest(&UartNs550);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
return XST_SUCCESS;
}

View file

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

View file

@ -0,0 +1,742 @@
/******************************************************************************
*
* 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.c
*
* This file contains the required functions for the 16450/16550 UART driver.
* Refer to the header file xuartns550.h for more detailed information.
*
* <pre>
* 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.
* </pre>
*
*****************************************************************************/
/***************************** 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.
* <br><br>
* This function and the XUartNs550_SetOptions() function modify shared data
* such that there may be a need for mutual exclusion in a multithreaded
* environment and if XUartNs550_SetOptions() if called from a handler.
*
*****************************************************************************/
unsigned int XUartNs550_Send(XUartNs550 *InstancePtr, u8 *BufferPtr,
unsigned int NumBytes)
{
unsigned int BytesSent;
u32 IerRegister;
/*
* Assert validates the input arguments
*/
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(BufferPtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
Xil_AssertNonvoid(((signed)NumBytes) >= 0);
/*
* Enter a critical region by disabling the UART transmit interrupts to
* allow this call to stop a previous operation that may be interrupt
* driven, only stop the transmit interrupt since this critical region
* is not really exited in the normal manner
*/
IerRegister = XUartNs550_ReadReg(InstancePtr->BaseAddress,
XUN_IER_OFFSET);
XUartNs550_WriteReg(InstancePtr->BaseAddress, XUN_IER_OFFSET,
IerRegister & ~XUN_IER_TX_EMPTY);
/*
* Setup the specified buffer to be sent by setting the instance
* variables so it can be sent with polled or interrupt mode
*/
InstancePtr->SendBuffer.RequestedBytes = NumBytes;
InstancePtr->SendBuffer.RemainingBytes = NumBytes;
InstancePtr->SendBuffer.NextBytePtr = BufferPtr;
/*
* Send the buffer using the UART and return the number of bytes sent
*/
BytesSent = XUartNs550_SendBuffer(InstancePtr);
/*
* The critical region is not exited in this function because of the way
* the transmit interrupts work. The other function called enables the
* tranmit interrupt such that this function can't restore a value to
* the interrupt enable register and does not need to exit the critical
* region
*/
return BytesSent;
}
/****************************************************************************/
/**
*
* This function will attempt to receive a specified number of bytes of data
* from the UART and store it into the specified buffer. This function is
* designed for either polled or interrupt driven modes. It is non-blocking
* such that it will return if no data has already received by the UART.
*
* In a polled mode, this function will only receive as much data as the UART
* can buffer, either in the receiver or in the FIFO if present and enabled.
* The application may need to call it repeatedly to receive a buffer. Polled
* mode is the default mode of operation for the driver.
*
* In interrupt mode, this function will start receiving and then the interrupt
* handler of the driver will continue receiving data until the buffer has been
* received. A callback function, as specified by the application, will be called
* to indicate the completion of receiving the buffer or when any receive errors
* or timeouts occur. Interrupt mode must be enabled using the SetOptions function.
*
* @param InstancePtr is a pointer to the XUartNs550 instance.
* @param BufferPtr is pointer to buffer for data to be received into
* @param NumBytes is the number of bytes to be received. A value of zero
* will stop a previous receive operation that is in progress in
* interrupt mode.
*
* @return The number of bytes received.
*
* @note
*
* The number of bytes is not asserted so that this function may be called with
* a value of zero to stop an operation that is already in progress.
*
*****************************************************************************/
unsigned int XUartNs550_Recv(XUartNs550 *InstancePtr, u8 *BufferPtr,
unsigned int NumBytes)
{
unsigned int ReceivedCount;
u32 IerRegister;
/*
* Assert validates the input arguments
*/
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(BufferPtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
Xil_AssertNonvoid(((signed)NumBytes) >= 0);
/*
* Enter a critical region by disabling all the UART interrupts to allow
* this call to stop a previous operation that may be interrupt driven
*/
IerRegister = XUartNs550_ReadReg(InstancePtr->BaseAddress,
XUN_IER_OFFSET);
XUartNs550_WriteReg(InstancePtr->BaseAddress, XUN_IER_OFFSET, 0);
/*
* Setup the specified buffer to be received by setting the instance
* variables so it can be received with polled or interrupt mode
*/
InstancePtr->ReceiveBuffer.RequestedBytes = NumBytes;
InstancePtr->ReceiveBuffer.RemainingBytes = NumBytes;
InstancePtr->ReceiveBuffer.NextBytePtr = BufferPtr;
/*
* Receive the data from the UART and return the number of bytes
* received
*/
ReceivedCount = XUartNs550_ReceiveBuffer(InstancePtr);
/*
* Restore the interrupt enable register to it's previous value such
* that the critical region is exited
*/
XUartNs550_WriteReg(InstancePtr->BaseAddress, XUN_IER_OFFSET,
IerRegister);
return ReceivedCount;
}
/****************************************************************************/
/**
*
* This function sends a buffer that has been previously specified by setting
* up the instance variables of the instance. This function is designed to be
* an internal function for the XUartNs550 component such that it may be called
* from a shell function that sets up the buffer or from an interrupt handler.
*
* This function sends the specified buffer of data to the UART in either
* polled or interrupt driven modes. This function is non-blocking such that
* it will return before the data has been sent by the UART.
*
* In a polled mode, this function will only send as much data as the UART can
* buffer, 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 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.
*
* @return NumBytes is the number of bytes actually sent (put into the
* UART tranmitter and/or FIFO).
*
* @note None.
*
*****************************************************************************/
unsigned int XUartNs550_SendBuffer(XUartNs550 *InstancePtr)
{
unsigned int SentCount = 0;
unsigned int BytesToSend = 0; /* default to not send anything */
unsigned int FifoSize;
u32 LsrRegister;
u32 IirRegister;
u32 IerRegister;
/*
* Read the line status register to determine if the transmitter is
* empty
*/
LsrRegister = XUartNs550_GetLineStatusReg(InstancePtr->BaseAddress);
/*
* If the transmitter is not empty then don't send any data, the empty
* room in the FIFO is not available
*/
if (LsrRegister & XUN_LSR_TX_BUFFER_EMPTY) {
/*
* Read the interrupt ID register to determine if FIFOs
* are enabled
*/
IirRegister = XUartNs550_ReadReg(InstancePtr->BaseAddress,
XUN_IIR_OFFSET);
/*
* When there are FIFOs, send up to the FIFO size. When there
* are no FIFOs, only send 1 byte of data
*/
if (IirRegister & XUN_INT_ID_FIFOS_ENABLED) {
/*
* Determine how many bytes can be sent depending on if
* the transmitter is empty, a FIFO size of N is really
* N - 1 plus the transmitter register
*/
if (LsrRegister & XUN_LSR_TX_EMPTY) {
FifoSize = XUN_FIFO_SIZE;
} else {
FifoSize = XUN_FIFO_SIZE - 1;
}
/*
* FIFOs are enabled, if the number of bytes to send
* is less than the size of the FIFO, then send all
* bytes, otherwise fill the FIFO
*/
if (InstancePtr->SendBuffer.RemainingBytes < FifoSize) {
BytesToSend =
InstancePtr->SendBuffer.RemainingBytes;
} else {
BytesToSend = FifoSize;
}
} else if (InstancePtr->SendBuffer.RemainingBytes > 0) {
/*
* Without FIFOs, we can only send 1 byte. We needed to
* check for non-zero remaining bytes in case this
* routine was called only to kick the transmitter and
* enable the UART interrupt
*/
BytesToSend = 1;
}
/*
* Fill the FIFO if it's present or the transmitter only from
* the the buffer that was specified
*/
for (SentCount = 0; SentCount < BytesToSend; SentCount++) {
XUartNs550_WriteReg(InstancePtr->BaseAddress,
XUN_THR_OFFSET,
InstancePtr->SendBuffer.NextBytePtr[SentCount]);
}
}
/*
* Update the buffer to reflect the bytes that were sent from it
*/
InstancePtr->SendBuffer.NextBytePtr += SentCount;
InstancePtr->SendBuffer.RemainingBytes -= SentCount;
/*
* Increment associated counters
*/
InstancePtr->Stats.CharactersTransmitted += SentCount;
/*
* If interrupts are enabled as indicated by the receive interrupt, then
* enable the transmit interrupt, it is not enabled continuously because
* it causes an interrupt whenever the FIFO is empty
*/
IerRegister = XUartNs550_ReadReg(InstancePtr->BaseAddress,
XUN_IER_OFFSET);
if (IerRegister & XUN_IER_RX_DATA) {
XUartNs550_WriteReg(InstancePtr->BaseAddress, XUN_IER_OFFSET,
IerRegister | XUN_IER_TX_EMPTY);
}
/*
* Return the number of bytes that were sent, althought they really were
* only put into the FIFO, not completely sent yet
*/
return SentCount;
}
/****************************************************************************/
/**
*
* This function receives a buffer that has been previously specified by setting
* up the instance variables of the instance. This function is designed to be
* an internal function for the XUartNs550 component such that it may be called
* from a shell function that sets up the buffer or from an interrupt handler.
*
* This function will attempt to receive a specified number of bytes of data
* from the UART and store it into the specified buffer. This function is
* designed for either polled or interrupt driven modes. It is non-blocking
* such that it will return if there is no data has already received by the
* UART.
*
* In a polled mode, this function will only receive as much data as the UART
* can buffer, either in the receiver or in the FIFO if present and enabled.
* The application may need to call it repeatedly to receive a buffer. Polled
* mode is the default mode of operation for the driver.
*
* In interrupt mode, this function will start receiving and then the interrupt
* handler of the driver will continue until the buffer has been received. A
* callback function, as specified by the application, will be called to indicate
* the completion of receiving the buffer or when any receive errors or timeouts
* occur. Interrupt mode must be enabled using the SetOptions function.
*
* @param InstancePtr is a pointer to the XUartNs550 instance.
*
* @return The number of bytes received.
*
* @note None.
*
*****************************************************************************/
unsigned int XUartNs550_ReceiveBuffer(XUartNs550 *InstancePtr)
{
u32 LsrRegister;
unsigned int ReceivedCount = 0;
/*
* Loop until there is not more data buffered by the UART or the
* specified number of bytes is received
*/
while (ReceivedCount < InstancePtr->ReceiveBuffer.RemainingBytes) {
/*
* Read the Line Status Register to determine if there is any
* data in the receiver/FIFO
*/
LsrRegister =
XUartNs550_GetLineStatusReg(InstancePtr->BaseAddress);
/*
* If there is a break condition then a zero data byte was put
* into the receiver, just read it and dump it and update the
* stats
*/
if (LsrRegister & XUN_LSR_BREAK_INT) {
(void)XUartNs550_ReadReg(InstancePtr->BaseAddress,
XUN_RBR_OFFSET);
XUartNs550_UpdateStats(InstancePtr, (u8)LsrRegister);
}
/*
* If there is data ready to be removed, then put the next byte
* received into the specified buffer and update the stats to
* reflect any receive errors for the byte
*/
else if (LsrRegister & XUN_LSR_DATA_READY) {
InstancePtr->ReceiveBuffer.NextBytePtr[ReceivedCount++] =
XUartNs550_ReadReg(InstancePtr->BaseAddress,
XUN_RBR_OFFSET);
XUartNs550_UpdateStats(InstancePtr, (u8)LsrRegister);
}
/*
* There's no more data buffered, so exit such that this
* function does not block waiting for data
*/
else {
break;
}
}
/*
* Update the receive buffer to reflect the number of bytes that was
* received
*/
InstancePtr->ReceiveBuffer.NextBytePtr += ReceivedCount;
InstancePtr->ReceiveBuffer.RemainingBytes -= ReceivedCount;
/*
* Increment associated counters in the statistics
*/
InstancePtr->Stats.CharactersReceived += ReceivedCount;
return ReceivedCount;
}
/****************************************************************************
*
* Sets the baud rate for the specified UART. Checks the input value for
* validity and also verifies that the requested rate can be configured to
* within the 3 percent error range for RS-232 communications. If the provided
* rate is not valid, the current setting is unchanged.
*
* This function is designed to be an internal function only used within the
* XUartNs550 component. It is necessary for initialization and for the user
* available function that sets the data format.
*
* @param InstancePtr is a pointer to the XUartNs550 instance.
* @param BaudRate to be set in the hardware.
*
* @return
* - XST_SUCCESS if everything configures as expected
* - XST_UART_BAUD_ERROR if the requested rate is not available
* because there was too much error due to the input clock
*
* @note None.
*
*****************************************************************************/
int XUartNs550_SetBaudRate(XUartNs550 *InstancePtr, u32 BaudRate)
{
u32 BaudLSB;
u32 BaudMSB;
u32 LcrRegister;
u32 Divisor;
u32 TargetRate;
u32 Error;
u32 PercentError;
/*
* Assert validates the input arguments
*/
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
/*
* Determine what the divisor should be to get the specified baud
* rater based upon the input clock frequency and a baud clock prescaler
* of 16
*/
Divisor = InstancePtr->InputClockHz / (BaudRate * 16UL);
/*
* check for too much error between the baud rate that will be generated
* using the divisor and the expected baud rate, integer division also
* truncates always positive
*/
TargetRate = Divisor * BaudRate * 16UL;
Error = InstancePtr->InputClockHz - TargetRate;
/*
* Error has total error now compute the percentage multiplied by 100 to
* avoid floating point calculations, should be less than 3% as per
* RS-232 spec
*/
PercentError = (Error * 100UL) / InstancePtr->InputClockHz;
if (PercentError > XUN_MAX_BAUD_ERROR_RATE) {
return XST_UART_BAUD_ERROR;
}
/*
* 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;
/*
* Save the baud rate in the instance so that the get baud rate function
* won't have to calculate it from the divisor
*/
InstancePtr->BaudRate = BaudRate;
/*
* Get the line control register contents and set the divisor latch
* access bit so the baud rate can be set
*/
LcrRegister = XUartNs550_GetLineControlReg(InstancePtr->BaseAddress);
XUartNs550_SetLineControlReg(InstancePtr->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(InstancePtr->BaseAddress, XUN_DRLS_OFFSET, 0xFF);
XUartNs550_WriteReg(InstancePtr->BaseAddress, XUN_DRLM_OFFSET,
BaudMSB);
XUartNs550_WriteReg(InstancePtr->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(InstancePtr->BaseAddress, LcrRegister);
return XST_SUCCESS;
}
/****************************************************************************/
/**
*
* This function is a stub handler that is the default handler such that if the
* application has not set the handler when interrupts are enabled, this
* function will be called. The function interface has to match the interface
* specified for a handler even though none of the arguments are used.
*
* @param CallBackRef is unused by this function.
* @param Event is unused by this function.
* @param ByteCount is unused by this function.
*
* @return None.
*
* @note None.
*
*****************************************************************************/
static void XUartNs550_StubHandler(void *CallBackRef, u32 Event,
unsigned int ByteCount)
{
(void) CallBackRef;
(void) Event;
(void) ByteCount;
/*
* Assert occurs always since this is a stub and should never be called
*/
Xil_AssertVoidAlways();
}

View file

@ -0,0 +1,455 @@
/******************************************************************************
*
* 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.h
*
* This driver supports the following features in the Xilinx 16450/16550
* compatible UART.
*
* - Dynamic data format (baud rate, data bits, stop bits, parity)
* - Polled mode
* - Interrupt driven mode
* - Transmit and receive FIFOs (16 bytes each for the 16550)
* - Access to the external modem control lines and the two discrete
* outputs
*
* The only difference between the 16450 and the 16550 is the addition of
* transmit and receive FIFOs in the 16550.
*
* <b>Initialization & Configuration</b>
*
* The XUartNs550_Config structure is used by the driver to configure itself.
* This configuration structure is typically created by the tool-chain based
* on HW build properties.
*
* To support multiple runtime loading and initialization strategies employed
* by various operating systems, the driver instance can be initialized in one
* of the following ways:
*
* - XUartNs550_Initialize(InstancePtr, DeviceId) - The driver looks
* up its own configuration structure created by the tool-chain based
* on an ID provided by the tool-chain.
*
* - XUartNs550_CfgInitialize(InstancePtr, CfgPtr, EffectiveAddr) - Uses a
* configuration structure provided by the caller. If running in a system
* with address translation, the provided virtual memory base address
* replaces the physical address present in the configuration structure.
*
* <b>Baud Rate</b>
*
* The UART has an internal baud rate generator that is clocked at a specified
* input clock frequency. Not all baud rates can be generated from some clock
* frequencies. The requested baud rate is checked using the provided clock for
* the system, and checked against the acceptable error range. An error may be
* returned from some functions indicating the baud rate was in error because
* it could not be generated.
*
* <b>Interrupts</b>
*
* The device does not have any way to disable the receiver such that the
* receive FIFO may contain unwanted data. The FIFOs are not flushed when the
* driver is initialized, but a function is provided to allow the user to reset
* the FIFOs if desired.
*
* The driver defaults to no interrupts at initialization such that interrupts
* must be enabled if desired. An interrupt is generated for any of the following
* conditions.
* - Transmit FIFO is empty
* - Data in the receive FIFO equal to the receive threshold
* - Data in the receiver when FIFOs are disabled
* - Any receive status error or break condition detected
* - Data in the receive FIFO for 4 character times without receiver
* activity
* - A change of a modem signal
*
* The application can control which interrupts are enabled using the SetOptions
* function.
*
* In order to use interrupts, it is necessary for the user to connect the driver
* interrupt handler, XUartNs550_InterruptHandler(), to the interrupt system of
* the application. This function does not save and restore the processor context
* such that the user must provide it. A handler must be set for the driver such
* that the handler is called when interrupt events occur. The handler is called
* from interrupt context and is designed to allow application specific
* processing to be performed.
*
* The functions, XUartNs550_Send() and XUartNs550_Recv(), are provided in the
* driver to allow data to be sent and received. They are designed to be used in
* polled or interrupt modes.
*
* @note
*
* The default configuration for the UART after initialization is:
* - 19,200 bps or XPAR_DEFAULT_BAUD_RATE if defined
* - 8 data bits
* - 1 stop bit
* - no parity
* - FIFO's are enabled with a receive threshold of 8 bytes
*
* <pre>
* 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.
* </pre>
*
*****************************************************************************/
#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 */

View file

@ -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.
*
* <pre>
* 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.
* </pre>
*
*****************************************************************************/
/***************************** 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.
* <br><br>
* The baud rates tested include: 1200, 2400, 4800, 9600, 19200, 38400, 57600
* and 115200.
*
*****************************************************************************/
int XUartNs550_SetDataFormat(XUartNs550 *InstancePtr,
XUartNs550Format *FormatPtr)
{
int Status;
u32 LcrRegister;
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(FormatPtr != NULL);
/*
* Verify the inputs specified are valid and return an error if any
* are not, without setting the data format
*/
if ((FormatPtr->DataBits > XUN_FORMAT_8_BITS) ||
(FormatPtr->Parity > XUN_FORMAT_EVEN_PARITY) ||
((FormatPtr->StopBits != XUN_FORMAT_2_STOP_BIT) &&
(FormatPtr->StopBits != XUN_FORMAT_1_STOP_BIT))) {
return XST_INVALID_PARAM;
}
/*
* Try to set the baud rate and if it's not successful then don't
* continue altering the data format, this is done first to avoid the
* format from being altered when an error occurs
*/
Status = XUartNs550_SetBaudRate(InstancePtr, FormatPtr->BaudRate);
if (Status != XST_SUCCESS) {
return Status;
}
/*
* Read the line control register which contains the parity, length and
* stop bits so they can be updated without affecting any other bits
*/
LcrRegister = XUartNs550_GetLineControlReg(InstancePtr->BaseAddress);
/*
* Set the length of data (8,7,6,5) by first clearing out the bits
* that control it in the register, then set the length in the register
*/
LcrRegister &= ~XUN_LCR_LENGTH_MASK;
LcrRegister |= FormatPtr->DataBits;
/*
* Set the number of stop bits in the line control register, if the
* number of stop bits is not 2, then it must be one which is the bit
* in the register cleared
*/
if (FormatPtr->StopBits == XUN_FORMAT_2_STOP_BIT) {
LcrRegister |= XUN_LCR_2_STOP_BITS;
} else {
LcrRegister &= ~XUN_LCR_2_STOP_BITS;
}
/*
* Set the parity by first clearing out the bits that control it in the
* register, then set the bits in the register, the default is no parity
* after clearing the register bits
*/
LcrRegister &= ~XUN_LCR_PARITY_MASK;
if (FormatPtr->Parity != XUN_FORMAT_NO_PARITY) {
/*
* Some form of parity is specified, set the bit indicating that
* parity is enabled, then setup even or odd, the default is odd
* after clearing the register bits
*/
LcrRegister |= XUN_LCR_ENABLE_PARITY;
if (FormatPtr->Parity == XUN_FORMAT_EVEN_PARITY) {
LcrRegister |= XUN_LCR_EVEN_PARITY;
}
}
/*
* Write the line control register out to save the new data format
* that has been created
*/
XUartNs550_SetLineControlReg(InstancePtr->BaseAddress, LcrRegister);
return XST_SUCCESS;
}
/****************************************************************************/
/**
*
* Gets the data format for the specified UART. The data format includes the
* baud rate, number of data bits, number of stop bits, and parity.
*
* @param InstancePtr is a pointer to the XUartNs550 instance.
* @param FormatPtr is a pointer to a format structure that will contain
* the data format after this call completes.
*
* @return None.
*
* @note None.
*
* @internal
*
* This function gets the state of the hardware rather than returning a state
* that has been stored to ensure that the hardware is correct.
*
*****************************************************************************/
void XUartNs550_GetDataFormat(XUartNs550 *InstancePtr,
XUartNs550Format *FormatPtr)
{
u32 LcrRegister;
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(FormatPtr != NULL);
/*
* Assert validates the input arguments
*/
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
/*
* Get the baud rate from the instance, this is not retrieved from the
* hardware because it is only kept as a divisor such that it is more
* difficult to get back to the divisor
*/
FormatPtr->BaudRate = InstancePtr->BaudRate;
/*
* Read the line control register which contains the parity, length and
* stop bits so they can be updated without affecting any other bits
*/
LcrRegister = XUartNs550_GetLineControlReg(InstancePtr->BaseAddress);
/*
* Set the length of data (8,7,6,5) by first clearing out the bits
* that control it in the register, then set the length in the register
*/
FormatPtr->DataBits = LcrRegister & XUN_LCR_LENGTH_MASK;
/*
* Set the number of stop bits by first clearing out the bits in that
* control it in the register, then set the bits in the register, the
* default is one stop bit after clearing the register bits
*/
if (LcrRegister & XUN_LCR_2_STOP_BITS) {
FormatPtr->StopBits = XUN_FORMAT_2_STOP_BIT;
} else {
FormatPtr->StopBits = XUN_FORMAT_1_STOP_BIT;
}
/*
* Determine what parity is set from the register and setup the format
* to correspond
*/
if ((LcrRegister & XUN_LCR_ENABLE_PARITY) == 0) {
FormatPtr->Parity = XUN_FORMAT_NO_PARITY;
} else {
/*
* Parity is enables, so determine if it's even or odd and set the
* format to correspond
*/
if (LcrRegister & XUN_LCR_EVEN_PARITY) {
FormatPtr->Parity = XUN_FORMAT_EVEN_PARITY;
} else {
FormatPtr->Parity = XUN_FORMAT_ODD_PARITY;
}
}
}

View file

@ -0,0 +1,82 @@
/******************************************************************************
*
* 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_g.c
*
* This file contains a configuration table that specifies the configuration of
* NS16550 devices in the system.
*
* <pre>
* 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.
* </pre>
*
******************************************************************************/
/***************************** 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
}
};

View file

@ -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.
*
* <pre>
* 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.
* </pre>
*
******************************************************************************/
#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 */

View file

@ -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.
*
* <pre>
* 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
* </pre>
*
*****************************************************************************/
/***************************** 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++;
}

View file

@ -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.
*
* <pre>
* 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.
* </pre>
*
******************************************************************************/
/***************************** 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);
}

View file

@ -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.
*
* <pre>
* 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.
* </pre>
*
******************************************************************************/
#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 */

View file

@ -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.
*
* <pre>
* 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.
* </pre>
*
*****************************************************************************/
/***************************** 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;
}

View file

@ -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.
*
* <pre>
* 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.
*
* </pre>
*
******************************************************************************/
/***************************** 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;
}

View file

@ -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.
*
* <pre>
* 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.
*
* </pre>
*
*****************************************************************************/
/***************************** 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);
}

View file

@ -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.
*
* <pre>
* 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.
* </pre>
*
*****************************************************************************/
/***************************** 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;
}