############################################################################### # # Copyright (C) 2011 - 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 # -------- ------ -------- ------------------------------------ # 2.0 adk 12/10/13 Updated as per the New Tcl API's # 2.0 bss 05/02/14 Modified to generate PITx_EXPIRED_MASK parameter # to fix CR#794167. ############################################################################## ############################################################ # Global interrupt handlers array, default handler routine ############################################################ array set interrupt_handlers "" set default_interrupt_handler "XNullHandler" ############################################################ # DRC procedure ############################################################ proc iomodule_drc {drv_handle} { } ############################################################ # "generate" procedure ############################################################ proc generate {drv_handle} { # Generate the following definitions in xparameters.h # 1. Common set common_params [list "NUM_INSTANCES" "DEVICE_ID" \ "C_BASEADDR" "C_HIGHADDR" "C_MASK" "C_FREQ"] # 2. UART set uart_params [list "C_USE_UART_RX" "C_USE_UART_TX" "C_UART_BAUDRATE" \ "C_UART_PROG_BAUDRATE" "C_UART_DATA_BITS" "C_UART_USE_PARITY" \ "C_UART_ODD_PARITY" "C_UART_RX_INTERRUPT" \ "C_UART_TX_INTERRUPT" "C_UART_ERROR_INTERRUPT"] # 3. FIT foreach i {1 2 3 4} { set fit${i}_params [list "C_USE_FIT${i}" "C_FIT${i}_No_CLOCKS" "C_FIT${i}_INTERRUPT"] } # 4. PIT foreach i {1 2 3 4} { set pit${i}_params [list "C_USE_PIT${i}" "C_PIT${i}_SIZE" "C_PIT${i}_EXPIRED_MASK" \ "C_PIT${i}_READABLE" "C_PIT${i}_PRESCALER" "C_PIT${i}_INTERRUPT"] } # 5. GPO foreach i {1 2 3 4} { set gpo${i}_params [list "C_USE_GPO${i}" "C_GPO${i}_SIZE"] } # 6. GPI foreach i {1 2 3 4} { set gpi${i}_params [list "C_USE_GPI${i}" "C_GPI${i}_SIZE" "C_GPI${i}_INTERRUPT"] } # 7. INTC set intc_params [list "C_INTC_USE_EXT_INTR" "C_INTC_INTR_SIZE" "C_INTC_HAS_FAST" "C_INTC_BASE_VECTORS"] # 8. IO BUS set io_params [list "C_USE_IO_BUS" "C_IO_BASEADDR" "C_IO_HIGHADDR" "C_IO_MASK"] set all_params [concat $common_params $uart_params \ $fit1_params $fit2_params $fit3_params $fit4_params \ $pit1_params $pit2_params $pit3_params $pit4_params \ $gpo1_params $gpo2_params $gpo3_params $gpo4_params \ $gpi1_params $gpi2_params $gpi3_params $gpi4_params \ $intc_params $io_params] eval [xdefine_include_file $drv_handle "xparameters.h" "XIOModule" $all_params] eval [xdefine_config_file $drv_handle "xiomodule_g.c" "XIOModule" $all_params] # Generate the following definitions as hexadecimal values in xparameters.h # 5. GPO foreach i {1 2 3 4} { set gpo${i}_params [list "C_GPO${i}_INIT"] } # 7. INTC set intc_params [list "C_INTC_LEVEL_EDGE" "C_INTC_POSITIVE"] set all_params [concat $gpo1_params $gpo2_params $gpo3_params $gpo4_params $intc_params] eval [xdefine_include_file_hex $drv_handle "xparameters.h" "XIOModule" $all_params] # 7. INTC: Set XPAR_IOMODULE_INTC_MAX_INTR_SIZE set max_intr_size 0 set periphs [hsi::utils::get_common_driver_ips $drv_handle] foreach periph $periphs { set periph_num_intr_internal [get_num_intr_internal $periph] set periph_num_intr_inputs [get_num_intr_inputs $periph] set periph_intr_size [expr $periph_num_intr_internal + $periph_num_intr_inputs] if {$max_intr_size < $periph_intr_size} { set max_intr_size $periph_intr_size } } # 7. INTC: Define XPAR_SINGLE_BASEADDR, XPAR_SINGLE_HIGHADDR, and XPAR_SINGLE_DEVICE_ID set periphs [hsi::utils::get_common_driver_ips $drv_handle] set count [llength $periphs] if {$count == 1} { hsi::utils::define_with_names $drv_handle [hsi::utils::get_common_driver_ips $drv_handle] "xparameters.h" \ "XPAR_IOMODULE_SINGLE_BASEADDR" "C_BASEADDR" \ "XPAR_IOMODULE_SINGLE_HIGHADDR" "C_HIGHADDR" \ "XPAR_IOMODULE_INTC_SINGLE_DEVICE_ID" "DEVICE_ID" } set config_inc [hsi::utils::open_include_file "xparameters.h"] puts $config_inc "#define XPAR_IOMODULE_INTC_MAX_INTR_SIZE $max_intr_size" # 7. INTC: Generate config table, vector tables iomodule_define_config_file $drv_handle $periphs $config_inc close $config_inc xdefine_canonical_xpars $drv_handle "xparameters.h" "IOModule" $all_params } ########################################################################## # Generate interrupt definitions in Configuration C file xiomodule_g.c # This file has the Config Table and vector tables for each iomodule # instance as required by Xilinx iomodule driver ########################################################################## proc iomodule_define_config_file {drv_handle periphs config_inc} { variable interrupt_handlers variable default_interrupt_handler # set isr_options to be XIN_SVC_SGL_ISR_OPTION as defined in xiomodule.h set isr_options XIN_SVC_SGL_ISR_OPTION set file_name "xiomodule_g.c" set drv_string "XIOModule" set args [list "DEVICE_ID" "C_BASEADDR" "C_IO_BASEADDR" "C_INTC_HAS_FAST" "C_INTC_BASE_VECTORS"] set filename [file join "src" $file_name] file delete $filename set config_file [open $filename w] 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" set tmp_filename [file join "src" "tmpconfig.c"] set tmp_config_file [open $tmp_filename w] puts $tmp_config_file "\n/*" puts $tmp_config_file "* The configuration table for devices" puts $tmp_config_file "*/\n" puts $tmp_config_file [format "%s_Config %s_ConfigTable\[\] =" $drv_string $drv_string] puts $tmp_config_file "\{" set start_comma "" foreach periph $periphs { puts $tmp_config_file [format "%s\t\{" $start_comma] set comma "" foreach arg $args { # Check if this is a driver parameter or a peripheral parameter set value [common::get_property CONFIG.$arg $drv_handle] if {[llength $value] == 0} { puts -nonewline $tmp_config_file [format "%s\t\t%s" $comma [::hsi::utils::get_ip_param_name $periph $arg]] } else { puts -nonewline $tmp_config_file [format "%s\t\t%s" $comma [hsi::utils::get_driver_param_name $drv_string $arg]] } set comma ",\n" } # add AckBeforeService as an arg to the config table - Ack Before for edge interrupts puts -nonewline $tmp_config_file [format "%s\t\t%s" $comma "(([::hsi::utils::get_ip_param_name $periph C_INTC_LEVEL_EDGE] << 16) | 0x7FF)"] # add the OPTIONS as an arg to the config table - default OPTIONS value is XIN_SVC_SGL_ISR_OPTION puts -nonewline $tmp_config_file [format "%s\t\t%s" $comma $isr_options] # add the FREQ as an arg to the config table puts -nonewline $tmp_config_file [format "%s\t\t%s" $comma [::hsi::utils::get_ip_param_name $periph "C_FREQ"] ] # add the BAUDRATE as an arg to the config table puts -nonewline $tmp_config_file [format "%s\t\t%s" $comma [::hsi::utils::get_ip_param_name $periph "C_UART_BAUDRATE"] ] # add the PIT use as an arg to the config table puts $tmp_config_file [format "%s\t\t\{" $comma ] for {set i 1} {$i <= 4} {incr i} { puts $tmp_config_file [format "\t\t\t%s," [::hsi::utils::get_ip_param_name $periph "C_USE_PIT${i}"] ] } puts -nonewline $tmp_config_file "\t\t\}" # add the PIT sizes as an arg to the config table puts $tmp_config_file [format "%s\t\t\{" $comma ] for {set i 1} {$i <= 4} {incr i} { puts $tmp_config_file [format "\t\t\t%s," [::hsi::utils::get_ip_param_name $periph "C_PIT${i}_SIZE"] ] } puts -nonewline $tmp_config_file "\t\t\}" # add the PIT sizes as an arg to the config table puts $tmp_config_file [format "%s\t\t\{" $comma ] for {set i 1} {$i <= 4} {incr i} { puts $tmp_config_file [format "\t\t\t%s," [::hsi::utils::get_ip_param_name $periph "C_PIT${i}_EXPIRED_MASK"] ] } puts -nonewline $tmp_config_file "\t\t\}" # add the PIT prescalers as an arg to the config table puts $tmp_config_file [format "%s\t\t\{" $comma ] for {set i 1} {$i <= 4} {incr i} { puts $tmp_config_file [format "\t\t\t%s," [::hsi::utils::get_ip_param_name $periph "C_PIT${i}_PRESCALER"] ] } puts -nonewline $tmp_config_file "\t\t\}" # add if PIT has readable counter as an arg to the config table puts $tmp_config_file [format "%s\t\t\{" $comma ] for {set i 1} {$i <= 4} {incr i} { puts $tmp_config_file [format "\t\t\t%s," [::hsi::utils::get_ip_param_name $periph "C_PIT${i}_READABLE"] ] } puts -nonewline $tmp_config_file "\t\t\}" # add the GPO initialization values as an arg to the config table puts $tmp_config_file [format "%s\t\t\{" $comma ] for {set i 1} {$i <= 4} {incr i} { puts $tmp_config_file [format "\t\t\t%s," [::hsi::utils::get_ip_param_name $periph "C_GPO${i}_INIT"] ] } puts -nonewline $tmp_config_file "\t\t\}" # generate the vector table for this iomodule instance iomodule_define_vector_table $periph $config_inc $tmp_config_file puts $config_inc "\n/******************************************************************/\n" puts -nonewline $tmp_config_file "\n\t\}" set start_comma ",\n" } puts $tmp_config_file "\n\};" close $tmp_config_file # Write out the extern definitions of handlers... foreach elem [array names interrupt_handlers] { puts $config_file [format "extern void %s (void *);" $elem ] } # copy over the tmp_config_file contents to config_file set tmp_config_file [open $tmp_filename r] while {![eof $tmp_config_file]} { gets $tmp_config_file line puts $config_file $line } close $tmp_config_file file delete -force $tmp_filename close $config_file } ########################################################################## # Define the vector table ########################################################################## proc iomodule_define_vector_table {periph config_inc config_file} { variable interrupt_handlers variable default_interrupt_handler set periph_name [common::get_property NAME $periph] # Get ports that are driving the interrupt set source_ports [hsi::utils::get_interrupt_sources $periph] set num_intr_inputs [get_num_intr_inputs $periph] set num_intr_internal [get_num_intr_internal $periph] if {$num_intr_inputs != [llength $source_ports]} { error "ERROR: Internal error: Number of interrupt inputs on $periph_name ($num_intr_inputs) is not the same as length of total number of interrupt sources ([llength $source_ports]). If any interrupt source is a vector then libgen does not support this use case" "" "hsi_error" return } set i 0 foreach source_pin $source_ports { set source_periph [hsi::get_cells -of_objects $source_pin ] if { [llength $source_periph ] == 0} { #external interrupt port case set width [hsi::utils::get_port_width $source_pin] for { set j 0 } { $j < $width } { incr j } { set source_port_name($i) "[common::get_property NAME $source_pin]_$j" set source_name($i) "system" set port_type($i) "global" set source_driver "" set source_interrupt_handler($i) $default_interrupt_handler incr i } } else { #peripheral interrrupt case set port_type($i) "local" set source_name($i) [common::get_property NAME $source_periph] set source_port_name($i) [common::get_property NAME $source_pin] set source_driver [hsi::get_drivers -filter "HW_INSTANCE==$source_periph"] set source_interrupt_handler($i) $default_interrupt_handler incr i } if {[string compare -nocase $source_driver ""] != 0} { set int_array [hsi::get_arrays interrupt_handler -of_objects $source_driver] if {[string compare -nocase $int_array ""] != 0} { set int_array_elems [xget_handle $int_array "ELEMENTS" "*"] foreach int_array_elem $int_array_elems { set int_port [common::get_property CONFIG.int_port $int_array_elem] set mhs_handle [common::get_property CONFIG.mhsinst $int_array_elem] if {[string compare -nocase $int_port $source_port_name] == 0 && \ $mhs_handle == $source_periph } { set source_interrupt_handler($i) [common::get_property CONFIG.int_handler $int_array_elem] # copy this handler to interrupt_handlers set arrsize [array size interrupt_handlers] iomodule_add_handler $source_interrupt_handler($i) set source_handler_arg($i) [common::get_property CONFIG.int_handler_arg $int_array_elem] if {[string compare -nocase $source_handler_arg($i) DEVICE_ID] == 0 } { set source_handler_arg($i) [::hsi::utils::get_ip_param_name $source_periph "DEVICE_ID"] } break } } } } } # Check if default_interrupt_handler has to have an extern definition if {[array size interrupt_handlers] < [llength $source_ports]} { iomodule_add_handler $default_interrupt_handler } # Write vector table to the config_file puts -nonewline $config_file ",\n\t\t\{" set comma "\n" for {set i 0} {$i < $num_intr_internal} {incr i} { puts $config_file [format "%s\t\t\t\{" $comma ] puts $config_file [format "\t\t\t\t%s," $default_interrupt_handler ] puts $config_file "\t\t\t\t(void *)XNULL" puts -nonewline $config_file "\t\t\t\}" set comma ",\n" } for {set i 0} {$i < $num_intr_inputs} {incr i} { puts $config_file [format "%s\t\t\t\{" $comma ] puts $config_file [format "\t\t\t\t%s," $source_interrupt_handler($i)] if {[llength $source_name($i)] == 0} { puts $config_file "\t\t\t\t(void *)XNULL" } else { puts $config_inc [format "#define XPAR_%s_%s_MASK %#08X" \ [string toupper $source_name($i)] \ [string toupper $source_port_name($i)] [expr 1 << $i]] puts $config_inc [format "#define XPAR_%s_%s_%s_INTR %d" \ [string toupper $periph_name] \ [string toupper $source_name($i)] \ [string toupper $source_port_name($i)] $i] if {[string compare -nocase "global" $port_type($i) ] != 0 && \ [string compare $source_interrupt_handler($i) $default_interrupt_handler ] != 0} { puts $config_file [format "\t\t\t\t(void *) %s" $source_handler_arg($i)] } else { puts $config_file "\t\t\t\t(void *) XNULL" } } puts -nonewline $config_file "\t\t\t\}" set comma ",\n" } puts $config_file "\n\t\t\}" } ########################################################################## # This procedure creates a unique list of # handlers that needs to have an extern defn. # in xparameters.h ########################################################################## proc iomodule_add_handler {handler} { variable interrupt_handlers set interrupt_handlers($handler) 1 } ########################################################################## # Given a list of arguments, define each as a canonical constant name, # using the driver name, in an include file. ########################################################################## proc xdefine_canonical_xpars {drv_handle file_name drv_string args} { set args [hsi::utils::get_exact_arg_list $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] # Print canonical parameters for each peripheral set device_id 0 foreach periph $periphs { puts $file_handle "" set periph_name [string toupper [common::get_property NAME $periph]] set canonical_name [format "%s_%s" $drv_string $device_id] # Make sure canonical name is not the same as hardware instance if { [string compare -nocase $canonical_name $periph_name] == 0 } { # Abort canonical names break } puts $file_handle "/* Canonical definitions for peripheral $periph_name */" puts [llength $args] foreach arg $args { if {[string first "_EXPIRED_MASK" $arg] > 0} { set charindex [string first "_EXPIRED_MASK" $arg] set size [string index $arg [expr $charindex - 1]] set sizearg [format "C_PIT%d_SIZE" $size] set lvalue [format "C_PIT%d_EXPIRED_MASK" $size] set lvalue [hsi::utils::get_driver_param_name $canonical_name $lvalue] set rvalue [common::get_property CONFIG.$sizearg $periph] set rvalue [expr pow(2, $rvalue) - 1] set rvalue [format "%.0f" $rvalue] set rvalue [format "0x%08X" $rvalue] } else { set lvalue [hsi::utils::get_driver_param_name $canonical_name $arg] # The commented out rvalue is the name of the instance-specific constant # set rvalue [::hsi::utils::get_ip_param_name $periph $arg] # The rvalue set below is the actual value of the parameter 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" } incr device_id puts $file_handle "" } # # Now redefine the Interrupt ID constants # xredefine_iomodule $drv_handle $file_handle puts $file_handle "\n/******************************************************************/\n" close $file_handle } ########################################################################## # iomodule redefines ########################################################################## proc xredefine_iomodule {drvhandle config_inc} { variable default_interrupt_handler # Next define interrupt IDs for each connected peripheral set periphs [hsi::utils::get_common_driver_ips $drvhandle] set device_id 0 set periph_name [string toupper "iomodule"] foreach periph $periphs { # Get the edk based name of peripheral for printing redefines set edk_periph_name [common::get_property NAME $periph] # Get ports that are driving the interrupt set source_ports [hsi::utils::get_interrupt_sources $periph] set i 0 lappend source_list foreach source_pin $source_ports { set source_periph($i) [hsi::get_cells -of_objects $source_pin ] if { [llength $source_periph($i) ] == 0} { #external interrupt port case set width [hsi::utils::get_port_width $source_pin] for { set j 0 } { $j < $width } { incr j } { set source_port_name($i) "[common::get_property NAME $source_pin]_$j" set source_name($i) "system" set port_type($i) "global" set source_driver "" set source_interrupt_handler($i) $default_interrupt_handler lappend source_list $source_name($i) incr i } } else { #peripheral interrrupt case set port_type($i) "local" set source_name($i) [common::get_property NAME $source_periph($i)] set source_port_name($i) [common::get_property NAME $source_pin] set source_driver [hsi::get_drivers -filter "HW_INSTANCE==$source_periph($i)"] set source_interrupt_handler($i) $default_interrupt_handler lappend source_list $source_name($i) incr i } } set num_intr_inputs [get_num_intr_inputs $periph] for {set i 0} {$i < $num_intr_inputs} {incr i} { # Skip global (external) ports if {$source_periph($i) == ""} { continue } set port_type($i) [common::get_property TYPE $source_periph($i)] if {[string compare -nocase $port_type($i) "global"] == 0} { continue } set drv [hsi::get_drivers -filter "HW_INSTANCE==$source_name($i)"] set iptype [common::get_property IPTYPE $source_periph($i)] # if {[llength $source_name($i)] != 0 && [llength $drv] != 0 && # [string compare -nocase $iptype "PERIPHERAL"] == 0} if {[llength $source_name($i)] != 0 && [llength $drv] != 0} { set instance [xfind_instance $drv $source_name($i)] set drvname [common::get_property NAME $drv] # # Handle reference cores, which have non-reference driver names # if {[string compare -nocase $drvname "touchscreen_ref"] == 0} { set drvname "touchscreen" } elseif {[string compare -nocase $drvname "ps2_ref"] == 0} { set drvname "ps2" set instance [expr $instance*2] if {[string match -nocase "*SYS_INTR2" $source_port_name($i)] == 1} { incr instance } } # # Define the interrupt vector IDs in xparameters.h for each core # that is connected to this iomodule. # set drvname [string toupper $drvname] # # Treat sources with multiple interrupt ports slightly different # by including the interrupt port name in the canonical constant # name # if { [lcount $source_list $source_name($i)] > 1} { set first_part [format "#define XPAR_%s_%s_%s_%s_%s_VEC_ID" \ $periph_name $device_id $drvname $instance \ [string toupper $source_port_name($i)]] } else { set first_part [format "#define XPAR_%s_%s_%s_%s_VEC_ID" \ $periph_name $device_id $drvname $instance] } set second_part [format "XPAR_%s_%s_%s_INTR" \ [string toupper $edk_periph_name] \ [string toupper $source_name($i)] \ [string toupper $source_port_name($i)] ] if {[string compare -nocase $drvname "generic"] != 0} { puts $config_inc "$first_part $second_part" } } } incr device_id } } ########################################################################## # Get the number of elements in the given list that match the given # entry. Assume elements are strings. ########################################################################## proc lcount {list match_entry} { set len [llength $list] set count 0 for {set i 0} {$i < $len} {incr i} { set entry [lindex $list $i] if { [string compare -nocase $entry $match_entry] == 0} { incr count } } return $count } ########################################################################## # Get the HW instance number for a particular device. This will be used to # enumerate the vector ID defines if more than one interrupt from the core # is connected to the interrupt controller. ########################################################################## proc xfind_instance {drvhandle instname} { set instlist [hsi::utils::get_common_driver_ips $drvhandle] set i 0 foreach inst $instlist { set name [common::get_property NAME $inst] if {[string compare -nocase $instname $name] == 0} { return $i } incr i } set i 0 return $i } ########################################################################## # Get the type of port, whether it is "local" (from an IP), or "global" # (from external source). ########################################################################## proc xget_port_type {periph} { set mhs [hsi::get_cells -of_object $periph] if {[llength $mhs] == 0} { return "global" } else { return "local" } } ########################################################################## # Get number of used external interrupts ########################################################################## proc get_num_intr_inputs {periph} { set intc_use_ext_intr [common::get_property CONFIG.C_INTC_USE_EXT_INTR $periph] if {$intc_use_ext_intr} { set num_intr_inputs [common::get_property CONFIG.C_INTC_INTR_SIZE $periph] } else { set num_intr_inputs 0 } return $num_intr_inputs } ########################################################################## # Get number of used internal interrupts ########################################################################## proc get_num_intr_internal {periph} { set c_use_uart_rx [common::get_property CONFIG.C_USE_UART_RX $periph] set c_uart_error_interrupt [common::get_property CONFIG.C_UART_ERROR_INTERRUPT $periph] set c_uart_rx_interrupt [common::get_property CONFIG.C_UART_RX_INTERRUPT $periph] set c_use_uart_tx [common::get_property CONFIG.C_USE_UART_TX $periph] set c_uart_tx_interrupt [common::get_property CONFIG.C_UART_TX_INTERRUPT $periph] set c_intc_use_ext_intr [common::get_property CONFIG.C_INTC_USE_EXT_INTR $periph] set c_intc_intr_size [common::get_property CONFIG.C_INTC_INTR_SIZE $periph] set num_intr_internal 0 if {$c_use_uart_tx * $c_use_uart_rx * $c_uart_error_interrupt} { set num_intr_internal 1 } if {$c_use_uart_tx * $c_uart_tx_interrupt} { set num_intr_internal 2 } if {$c_use_uart_rx * $c_uart_rx_interrupt} { set num_intr_internal 3 } foreach kind {PIT FIT GPI} suffix {"SIZE" "No_CLOCKS" "INTERRUPT"} intbit {3 7 11} { foreach it {1 2 3 4} { set c_use_it [expr [common::get_property CONFIG.C_${kind}${it}_${suffix} $periph] > 0] set c_it_interrupt [common::get_property CONFIG.C_${kind}${it}_INTERRUPT $periph] if {$c_use_it * $c_it_interrupt} { set num_intr_internal [expr $intbit + $it] } } } # If any external interrupts are used - return 16 since in that case all internal interrupts # must be accounted for because external interrupts start at bit position 16 if {$c_intc_use_ext_intr} { return 16 } return $num_intr_internal } ########################################################################## # Define parameters as hexadecimal values in include file. Derived from # xdefine_include_file in "$XILINX_EDK/data/datastructure/xillib_sw.tcl". ########################################################################## proc xdefine_include_file_hex {drv_handle file_name drv_string args} { set args [hsi::utils::get_exact_arg_list $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] # Print all parameters for all peripherals as hexadecimal strings set device_id 0 foreach periph $periphs { puts $file_handle "" puts $file_handle "/* Additional definitions for peripheral [string toupper [common::get_property NAME $periph]] */" foreach arg $args { set value [common::get_property CONFIG.$arg $periph] if {[llength $value] == 0} { set value 0 } # Convert binary string starting with "0b" to hexadecimal if {[string first "0b" $value] == 0} { set value_int 0 for {set i 2} {$i < [string length $value]} {incr i} { set value_int [expr $value_int * 2 + [string index $value $i]] } set value [format "0x%08x" $value_int] } puts $file_handle "#define [::hsi::utils::get_ip_param_name $periph $arg] $value" } puts $file_handle "" } puts $file_handle "\n/******************************************************************/\n" close $file_handle } ############################################################################## # Define parameters in xparameters.h and generate PIT_EXPIRED_MASK parameter ############################################################################## proc xdefine_include_file {drv_handle file_name drv_string args} { set args [hsi::utils::get_exact_arg_list $args] # Open include file set file_handle [hsi::utils::open_include_file $file_name] set flag 0 # 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] } # Check if it is a driver parameter lappend newargs foreach arg $args { set value [common::get_property CONFIG.$arg $drv_handle] if {[llength $value] == 0} { lappend newargs $arg } else { puts $file_handle "#define [hsi::utils::get_driver_param_name $drv_string $arg] [common::get_property $arg $drv_handle]" } } set args $newargs # Print all parameters for all peripherals set device_id 0 foreach periph $periphs { puts $file_handle "" puts $file_handle "/* Definitions for peripheral [string toupper [common::get_property NAME $periph]] */" foreach arg $args { if {[string compare -nocase "DEVICE_ID" $arg] == 0} { set value $device_id incr device_id } else { if {[string first "_EXPIRED_MASK" $arg] > 0} { set charindex [string first "_EXPIRED_MASK" $arg] set size [string index $arg [expr $charindex - 1]] set sizearg [format "C_PIT%d_SIZE" $size] set lvalue [format "PIT%d_EXPIRED_MASK" $size] set lvalue [format "XPAR_%s_%s" [string toupper [common::get_property NAME $periph]] $lvalue] set rvalue [common::get_property CONFIG.$sizearg $periph] set rvalue [expr pow(2, $rvalue) - 1] set rvalue [format "%.0f" $rvalue] set rvalue [format "0x%08X" $rvalue] set flag 1 } else { set value [common::get_property CONFIG.$arg $periph] } } if {[llength $value] == 0} { set value 0 } set value [hsi::utils::format_addr_string $value $arg] if {[string compare -nocase "HW_VER" $arg] == 0} { puts $file_handle "#define [::hsi::utils::get_ip_param_name $periph $arg] \"$value\"" } else { if {$flag == 0} { puts $file_handle "#define [::hsi::utils::get_ip_param_name $periph $arg] $value" } else { puts $file_handle "#define $lvalue $rvalue" set flag 0 } } } puts $file_handle "" } puts $file_handle "\n/******************************************************************/\n" close $file_handle }