#!/usr/bin/perl | |
# | |
# Copyright Statement: | |
# -------------------- | |
# This software is protected by Copyright and the information contained | |
# herein is confidential. The software may not be copied and the information | |
# contained herein may not be used or disclosed except with the written | |
# permission of MediaTek Inc. (C) 2006 | |
# | |
# BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES | |
# THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") | |
# RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON | |
# AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, | |
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF | |
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. | |
# NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE | |
# SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR | |
# SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH | |
# THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO | |
# NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S | |
# SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. | |
# | |
# BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE | |
# LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, | |
# AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, | |
# OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO | |
# MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. | |
# | |
# THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE | |
# WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF | |
# LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND | |
# RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER | |
# THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC). | |
# | |
#***************************************************************************** | |
#* | |
#* Filename: | |
#* --------- | |
#* ckFlashInfo.pl | |
#* | |
#* Project: | |
#* -------- | |
#* | |
#* | |
#* Description: | |
#* ------------ | |
#* This script will | |
#* 1. parse PartNumber_cfg.ini to obtain a series of part numbers | |
#* 2. read MDL to get flash ID of these part numbers | |
#* 3. compare these flash ID and report error if there are duplicated ones | |
#* | |
#* Author: | |
#* ------- | |
#* Claudia Lo (mtk01876) | |
#* | |
#*============================================================================ | |
#* HISTORY | |
#* Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!! | |
#*------------------------------------------------------------------------------ | |
#* $Revision$ | |
#* $Modtime$ | |
#* $Log$ | |
#* | |
#* | |
#*------------------------------------------------------------------------------ | |
#* Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!! | |
#*============================================================================ | |
#****************************************************************************/ | |
#**************************************************************************** | |
# Included Modules | |
#**************************************************************************** | |
use strict; | |
use Win32::OLE qw(in with); | |
use Win32::OLE::Const 'Microsoft Excel'; | |
$Win32::OLE::Warn = 3; # die on errors... | |
#**************************************************************************** | |
# Constants | |
#**************************************************************************** | |
my $CKFLASHINFO_VERNO = " v0.00"; | |
# v0.00 , by Claudia at 2009/12/11 , initial version | |
# | |
my $DebugPrint = 1; # 1 for debug; 0 for non-debug | |
my $PARTNUMBER_CFG_INI = $ARGV[0]; | |
my $MEMORY_DEVICE_LIST_XLS = Win32::GetCwd()."\\".$ARGV[1]; | |
my $MEMORY_DEVICE_LIST_XLS_E = $ARGV[1]; | |
my $CUSTOM_MEMORY_DEVICE_HDR = $ARGV[2]; | |
# to align error message file name format | |
$MEMORY_DEVICE_LIST_XLS_E =~ s/^.\\|^\\//; | |
#**************************************************************************** | |
# parse custom_MemoryDevice.h to extract MEMORY_DEVICE_TYPE & PART_NUMBER | |
#**************************************************************************** | |
open CUSTOM_MEMORY_DEVICE_HDR, "<$CUSTOM_MEMORY_DEVICE_HDR" or &error_handler("$CUSTOM_MEMORY_DEVICE_HDR: file error!", __FILE__, __LINE__); | |
my $MEMORY_DEVICE_TYPE; | |
while (<CUSTOM_MEMORY_DEVICE_HDR>) | |
{ | |
if (/^#define\s+MEMORY_DEVICE_TYPE\s+(\w*)/) | |
{ | |
$MEMORY_DEVICE_TYPE = $1; | |
} | |
} | |
close CUSTOM_MEMORY_DEVICE_HDR; | |
&error_handler("$CUSTOM_MEMORY_DEVICE_HDR: MEMORY_DEVICE_TYPE undefined!", __FILE__, __LINE__) if (!defined $MEMORY_DEVICE_TYPE); | |
if ($DebugPrint == 1) | |
{ | |
print "MEMORY_DEVICE_TYPE: $MEMORY_DEVICE_TYPE\n"; | |
} | |
#**************************************************************************** | |
# parse EMI database to get flash IDs | |
#**************************************************************************** | |
my %PN_FlashID; | |
if ($MEMORY_DEVICE_TYPE eq 'NOR_RAM_MCP') | |
{ | |
&fs_parse_mdl_key_content($MEMORY_DEVICE_LIST_XLS, 'NOR_RAM_MCP', 'Part Number', 'Flash ID', \%PN_FlashID); | |
} # if ($MEMORY_DEVICE_TYPE eq 'NOR_RAM_MCP') | |
elsif ($MEMORY_DEVICE_TYPE eq 'NOR_LPSDRAM_MCP') | |
{ | |
&fs_parse_mdl_key_content($MEMORY_DEVICE_LIST_XLS, 'NOR_RAM_MCP', 'Part Number', 'Flash ID', \%PN_FlashID); | |
}# elsif ($MEMORY_DEVICE_TYPE eq 'NOR_LPSDRAM_MCP') | |
elsif ($MEMORY_DEVICE_TYPE eq 'LPSDRAM') | |
{ | |
&fs_parse_mdl_key_content($MEMORY_DEVICE_LIST_XLS, 'LPSDRAM', 'Part Number', 'Flash ID', \%PN_FlashID); | |
}# elsif ($MEMORY_DEVICE_TYPE eq 'LPSDRAM') | |
else | |
{ | |
&error_handler("$CUSTOM_MEMORY_DEVICE_HDR: invalid MEMORY_DEVICE_TYPE!", __FILE__, __LINE__); | |
} | |
#**************************************************************************** | |
# parse PartNumber_cfg.ini to obtain a series of part numbers, | |
# retrieve their flash IDs, and check whether the flash IDs are duplicated | |
#**************************************************************************** | |
open PARTNUMBER_CFG_INI_HANDLE, "<$PARTNUMBER_CFG_INI"; | |
my %PN_FlashID_cfg; | |
while (<PARTNUMBER_CFG_INI_HANDLE>) | |
{ | |
if (/([\w|\-]+)\n*/) | |
{ | |
my $part_number = $1; | |
if ($DebugPrint == 1) | |
{ | |
print "Part Number: $1, flash ID: $PN_FlashID{$part_number}\n"; | |
} | |
&error_handler("$PARTNUMBER_CFG_INI: Invalid part number $part_number! Please assign valid part numbers!\n", __FILE__, __LINE__) if (!defined $PN_FlashID{$part_number}); | |
if ((defined $PN_FlashID{$part_number}) and ($PN_FlashID{$part_number} =~ /\s*0x[A-Fa-f0-9]{4}\s*,*/)) | |
{ | |
my @id_list = split /\,/, $PN_FlashID{$part_number}; | |
foreach (@id_list) | |
{ | |
if (/\s*0x[A-Fa-f0-9]{4}\s*/) | |
{ | |
} | |
else | |
{ | |
&error_handler("$PARTNUMBER_CFG_INI: Invalid Flash ID of part number $part_number! Please choose another part number with valid flash ID!\n", __FILE__, __LINE__); | |
} | |
} | |
foreach (keys %PN_FlashID_cfg) | |
{ | |
&error_handler("$PARTNUMBER_CFG_INI: Duplicated Flash ID of part number $_ and $part_number! Please assign part numbers with different flash IDs, otherwise the flash tool cannot determine which load to download!\n", __FILE__, __LINE__) if (uc($PN_FlashID{$part_number}) eq uc($PN_FlashID_cfg{$_})); | |
} | |
} | |
else | |
{ | |
&error_handler("$PARTNUMBER_CFG_INI: Invalid Flash ID of part number $part_number! Please choose another part number with valid flash ID!\n", __FILE__, __LINE__); | |
} | |
$PN_FlashID_cfg{$part_number} = $PN_FlashID{$part_number}; | |
} | |
} | |
close PARTNUMBER_CFG_INI_HANDLE; | |
if ($DebugPrint == 1) | |
{ | |
my $idx = 1; | |
foreach (keys %PN_FlashID_cfg) | |
{ | |
print "Part Number $idx: $_, flash ID $PN_FlashID_cfg{$_}\n"; | |
$idx++; | |
} | |
} | |
exit; | |
#**************************************************************************** | |
# subroutine: xls_cell_value | |
# return: excel cell value no matter it's in merge area or not | |
# input: $sheet: specified Excel Sheet | |
# $row: specified row number | |
# $col: specified column number | |
#**************************************************************************** | |
sub xls_cell_value | |
{ | |
my ($sheet, $row, $col) = @_; | |
if ($sheet->Cells($row, $col)->{'MergeCells'}) | |
{ | |
my $ma = $sheet->Cells($row, $col)->{'MergeArea'}; | |
return ($ma->Cells(1, 1)->{'Value'}); | |
} | |
else | |
{ | |
return ($sheet->Cells($row, $col)->{'Value'}) | |
} | |
} | |
#**************************************************************************** | |
# subroutine: fs_parse_mdl_key_content | |
# return: hash of matching rows and indexing rows | |
# input: $file: excel file to be read | |
# $sheet: sheet to open | |
# $key: the column in the file to be keys | |
# $content: the column in the file to be contents | |
# $target_href: the output hash of all key-content mappings in the file | |
#**************************************************************************** | |
sub fs_parse_mdl_key_content | |
{ | |
my ($file, $sheet, $key, $content, $target_href) = @_; | |
### get already active Excel application or open new | |
my $Excel = Win32::OLE->GetActiveObject('Excel.Application') || Win32::OLE->new('Excel.Application', 'Quit'); | |
### copy the Excel file to a temp file and open it; | |
### this will prevent error due to simultaneous Excel access | |
my $Book = $Excel->Workbooks->Open($file); | |
### | |
my $WorkSheet = $Book->Worksheets($sheet); | |
### find the key and content columns | |
my ($key_col, $content_col); | |
my $col = 1; | |
while (defined &xls_cell_value($WorkSheet, 1, $col)) | |
{ | |
if (&xls_cell_value($WorkSheet, 1, $col) eq $key) | |
{ | |
$key_col = $col | |
} | |
if (&xls_cell_value($WorkSheet, 1, $col) eq $content) | |
{ | |
$content_col = $col | |
} | |
$col++; | |
} | |
if ($DebugPrint == 1) | |
{ | |
print "key_col = $key_col; content_col = $content_col\n"; | |
} | |
### collect all key contents in the output href | |
my $row = 2; | |
my $empty_flag = 0; # exit if two consecutive empty lines are encountered | |
while (1) | |
{ | |
if (!defined &xls_cell_value($WorkSheet, $row, $key_col)) | |
{ | |
if ($empty_flag == 0) | |
{ | |
$empty_flag = 1; | |
} | |
elsif ($empty_flag == 1) | |
{ | |
last; | |
} | |
} | |
else | |
{ | |
$empty_flag = 0; | |
} | |
my $key_val = &xls_cell_value($WorkSheet, $row, $key_col); | |
my $content_val = &xls_cell_value($WorkSheet, $row, $content_col); | |
if ($content_val =~ /\w+/) | |
{ | |
my @key_list = split /\s/, $key_val; | |
#print "key_val = $key_val, content_val = $content_val\n"; | |
foreach (@key_list) | |
{ | |
if (/\w+/) | |
{ | |
if (!defined $target_href->{$_}) | |
{ | |
$target_href->{$_} = $content_val; | |
} | |
} | |
} | |
} | |
$row++; | |
} | |
### close the temp Excel file | |
$Book->Close(1); | |
} | |
#**************************************************************************** | |
# subroutine: error_handler | |
# input: $error_msg: error message | |
#**************************************************************************** | |
sub error_handler | |
{ | |
my ($error_msg, $file, $line_no) = @_; | |
my $final_error_msg = "CKFLASHID ERROR: $error_msg at $file line $line_no\n"; | |
print $final_error_msg; | |
die $final_error_msg; | |
} |