"""
/*
 * Copyright (c) 2016-2017, Texas Instruments Incorporated
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * *  Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * *  Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * *  Neither the name of Texas Instruments Incorporated nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
Created By: Nima Eskandari
Description: Creates a .h file from TI TXT HEX file.
"""

# TODO: Change the sourcePath variable to the path of the TI HEX TXT file.

sourcePath = "C:\\PATH TO THE TI TXT  HEX FILE\\Debug\\FR2311_blinky.txt"
imagePath = "msp430fr_image.h"

class MemorySection:

    def __init__(self, content):
        self.Content = content
        self.ContentSplitBySpace = []
        content_split_by_line = self.Content.split('\n')
        for line in content_split_by_line:
            line_split_by_space = line.split(' ')
            for i in range(0, len(line_split_by_space)):
                line_split_by_space[i] = line_split_by_space[i].replace(' ', '')
                if line_split_by_space[i] != '':
                    self.ContentSplitBySpace.append(line_split_by_space[i])

        self.StartAddress = self.get_start_address()
        self.SizeInBytes = self.get_number_of_bytes()
        self.SizeInWords = int(self.SizeInBytes / 2)
        self.ContentInBytes = self.get_content_in_bytes()
        self.ContentInWords = self.get_content_in_words()
        self.HexPaddedContentInWords = self.get_hex_padded_content_in_words()
        self.HexPaddedContentInBytes = self.get_hex_padded_content_in_bytes()

    def print_section(self):
        print("Start Address: " + self.StartAddress)
        print("Size in words: " + str(self.SizeInWords))
        print("Content in Bytes: ")
        print(self.HexPaddedContentInBytes)

    def get_start_address(self):
        return "0x" + self.ContentSplitBySpace[0]

    def get_number_of_bytes(self):
        return len(self.ContentSplitBySpace) - 1

    def get_content_in_bytes(self):
        return self.ContentSplitBySpace[1:]

    def get_content_in_words(self):
        content_in_words = []
        for i in range(0, self.SizeInWords):
            value = self.ContentInBytes[2*i + 1] + self.ContentInBytes[2*i]
            content_in_words.append(value)
        return content_in_words

    def get_hex_padded_content_in_words(self):
        hex_padded_content_in_words = []
        for i in range(0, self.SizeInWords):
            value = "0x" + self.ContentInBytes[2 * i + 1] + self.ContentInBytes[2 * i]
            hex_padded_content_in_words.append(value)
        return hex_padded_content_in_words

    def get_hex_padded_content_in_bytes(self):
        hex_padded_content_in_bytes = []
        for i in range(0, self.SizeInBytes):
            value = "0x" + self.ContentInBytes[i]
            hex_padded_content_in_bytes.append(value)
        return hex_padded_content_in_bytes


imageFile = open(imagePath, "w")
sourceFile = open(sourcePath, "r")

sourceContent = sourceFile.read()
sourceFile.close()

splitContents = sourceContent.split("@")
memorySections = []
for splitContent in splitContents:
    splitContent = splitContent.replace('q', '')
    if splitContent != '':
        memorySections.append(MemorySection(splitContent))

for memorySection in memorySections:
    memorySection.print_section()

# Write To File

# fram
fram_begin = "uint8_t fram[] =\n{\n"
fram_end = "\n};\n"

fram_content = ""

for memorySection in memorySections:
    bytes = memorySection.HexPaddedContentInBytes
    fram_content += "//" + memorySection.StartAddress + "\n"
    for i in range(0, len(bytes)):
        fram_content += bytes[i] + ", "
        if i % 8 == 7:
            fram_content += "\n"
    fram_content += "\n"

# fram address
fram_address_begin = "const uint32_t fram_address[] =\n{\n"
fram_address_end = "\n};\n"

fram_address_content = ""
for memorySection in memorySections:
    start_address = memorySection.StartAddress
    fram_address_content += start_address + ", "

# fram lenght
fram_length_begin = "const uint32_t fram_length_of_sections[] =\n{\n"
fram_length_end = "\n};\n"

fram_length_content = ""
for memorySection in memorySections:
    sizeInWords = memorySection.SizeInBytes
    fram_length_content += str(sizeInWords) + ", "

# fram constants
fram_sections_begin = "const uint32_t fram_sections    = "
fram_sections_end = ";\n"

fram_constants = \
    "const uint32_t fram_termination = 0x00000000; /*Check device data sheet*/\n"\
    + "const uint32_t fram_start       = 0x00000000; /*Check device data sheet*/\n"\
    + "const uint32_t fram_finish      = 0x00000000; /*Check device data sheet*/\n"\
    + "const uint32_t fram_length      = 0x00000000; /*Check device data sheet*/\n"

imageFile.write("/*"
                + "\n* This file was automatically generated."
                + "\n* The memory sections should be quickly double checked."
                + "\n* Some sections such ad Start,Finish, Termination and Length must be"
                + "\n* modified based on device datasheet. (These values aren't used by the"
                + "\n* default program."
                + "\n* Created by: Nima Eskandari"
                + "\n*/\n")

imageFile.write("\n" + fram_begin + fram_content + fram_end + "\n")
imageFile.write("\n" + fram_address_begin + fram_address_content + fram_address_end + "\n")
imageFile.write("\n" + fram_length_begin + fram_length_content + fram_length_end + "\n")
imageFile.write("\n" + fram_sections_begin + str(len(memorySections)) + fram_sections_end)
imageFile.write("\n" + fram_constants + "\n")

imageFile.close()
