# convert_hex_2_bhex.pl
# converts input 32bit hexadecimal file to flash load format
# computes unsigned 16bit checksum of memory 20000..ffe7f and writes result to
# 00ffef8 = 0x0ffe80 + (30-1)*4
# When reading Ignores lines that consists spaces
# written by: Shimon Samoocha
# 18/October/2007
$error_msg = "\n usage: convert_hex_2_flash.pl <hex_file_name> <bhex_file_name> <checksum_hex_filename> ";
(my $hex_file_name    =  $ARGV[0]) || die $error_msg;
(my $bhex_file_name  =  $ARGV[1]) || die $error_msg;
(my $checksum_hex_file_name  =  $ARGV[2]) || die $error_msg;

#open input file
(open my $hex_fp,   "<", $hex_file_name)   || die "ERROR: unable to open $hex_file_name file";

#open output byte hex
(open  $bhex_fp, ">", $bhex_file_name) || die "ERROR: unable to open $bhex_file_name";

#open output dword hex file
(open  $checksum_hex_fp, ">", $checksum_hex_file_name) || die "ERROR: unable to open $checksum_hex_file_name";

my $read_lines_number  = 0;
my $legal_lines_number = 0;
$next_flash_address = hex($flash_base);
my $u16_checksum = 0;

while (!eof($hex_fp) )
{#while

  $read_lines_number++;

  # reads next line from input hexadecimal file
  my $line_str = <$hex_fp>;

  if($read_lines_number != (0x0ffe80/4+29+1) )
  {
     printf $checksum_hex_fp $line_str;
  }


  chomp $line_str;

  # if read line consists space ignore
  if((index($line_str, " ")==-1)
     &&
     (length($line_str)>7))
  {# legal input line
    $legal_lines_number++;
    $line_dec = 0 + hex($line_str);


    # computes checksum
    if( ($legal_lines_number > (020000/4)) & ($legal_lines_number <= (0x00ffe80/4)) )
    {
      $u16_checksum = $u16_checksum + (0x0ffff & $line_dec) +  (0x0ffff & ($line_dec>>16));
    }

    # change print number to checksum if these is checksum line
    if($legal_lines_number == (0x0ffe80/4+30+1))
    {
      $line_dec = $u16_checksum;

      # report to dat file
      $next_print_line = "";
      $next_print_line = sprintf("0x%08x\n", ($line_dec&0x0ffffffff));
      printf $checksum_hex_fp $next_print_line;

    }

    # if line is checksum line write checksum instead of read data
    for($_=0; $_<4; $_++)
    {
      $next_print_line = "";
      $next_byte =  $line_dec&0x0ff;
      $next_print_line = sprintf("%02x\n", ($line_dec&0x0ff));
      printf $bhex_fp $next_print_line;
      $line_dec >>= 8;          # shifts next byte
      $next_flash_address += 2; # advance by 2 since HW requirement
    }
  }# legal input line

}#while
print "read lines #:$read_lines_number, legal lines #:$legal_lines_number, \n";
$next_print_line = "";
$next_print_line = sprintf("u16_checksum: 0x%04x\n", $u16_checksum);
print "$next_print_line";
printf("output file byte size #: 0x%08x", $legal_lines_number*4);
close $hex_fp;
close $bhex_fp;
close $checksum_hex_fp;