1# Copyright 2022 Cypress Semiconductor Corporation 2# SPDX-License-Identifier: Apache-2.0 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15 16# From https://wiki.tcl-lang.org/page/constants 17proc const {name value} { 18 uplevel 1 [list set $name $value] 19 uplevel 1 [list trace var $name w {error constant} ] 20} 21 22# Constant 23const REQ_PERI_CLOCK_ACCURACY 0.0025 24const EXPECTED_FREQ_MAX 100250 25const EXPECTED_FREQ_MIN 99750 26 27# Name of returned parameters 28const UPPER_DIV "upperDiv" 29const LOWER_DIV "lowerDiv" 30const BEST_DIV "bestDiv" 31const RESULT "result" 32 33# Result constant 34const THE_DIV_VALUE_IS_FOUND 0 35const THE_DIV_VALUE_IS_NOT_FOUND 1 36const RESULT_BAD_ACCURACY 2 37 38# Send data to personality 39proc output_results {upper_div lower_div best_div result} { 40 puts $::channelName "param:$::UPPER_DIV=$upper_div" 41 puts $::channelName "param:$::LOWER_DIV=$lower_div" 42 puts $::channelName "param:$::BEST_DIV=$best_div" 43 puts $::channelName "param:$::RESULT=$result" 44} 45 46# The number of input parameters 47const NUM_OF_ARG 2 48 49# Main function 50proc main {} { 51 if {$::argc != $::NUM_OF_ARG} { 52 error "Script requires two input parameters" 53 return 0 54 } 55 56 set peri_clock_freq [lindex $::argv 0] 57 set peri_clock_accuracy [lindex $::argv 1] 58 59 # Set default statuses 60 set upper_div 0 61 set lower_div 0 62 set best_div 0 63 set result $::THE_DIV_VALUE_IS_FOUND 64 65 # Check accuracy 66 if {$peri_clock_accuracy > $::REQ_PERI_CLOCK_ACCURACY} { 67 set result $::RESULT_BAD_ACCURACY 68 } else { 69 70 set upper_freq_limit_real [expr {$::EXPECTED_FREQ_MAX / (1 + $peri_clock_accuracy)}] 71 set lower_freq_limit_real [expr {$::EXPECTED_FREQ_MIN / (1 - $peri_clock_accuracy)}] 72 73 set upper_div [expr {floor($peri_clock_freq / $lower_freq_limit_real)}] 74 set lower_div [expr {ceil($peri_clock_freq / $upper_freq_limit_real)}] 75 76 if {$lower_div > $upper_div} { 77 set result $::THE_DIV_VALUE_IS_NOT_FOUND 78 } else { 79 set best_div [expr {$lower_div + round(($upper_div - $lower_div) / 2)}] 80 } 81 } 82 83 if {$result != $::THE_DIV_VALUE_IS_FOUND} { 84 set upper_div 0 85 set lower_div 0 86 set best_div 0 87 } 88 89 output_results $upper_div $lower_div $best_div $result 90} 91 92 93# Select output methods 94set channelName stdout 95if {[chan names ModusToolbox] eq "ModusToolbox"} { 96 set channelName ModusToolbox 97} 98 99# Start calculation 100main 101