import setup
import random
import pdb
import time
import words
import time
import sys
import logging
import datetime
import argparse
import io
import os.path
import serial

UART_BLOCK = 0x1000
SKIP_VERIFY = False

###############################################################################
# Memory Read/Write
###############################################################################
def sendcmd_scpu_run(addr):
    address = int(addr,16)
    print('send_scpu_run command..')
    setup.send_scpu_run(address)
    
def memory_specific_bin_program(addr, file, size = 0):
    logging.info('\nProgramming .. from %s [size=%d]' %(file, size))
    rdata = list(setup.file_read_binary(file))
    if size == 0:
        size = len(rdata)
    setup.flash_write(addr, rdata, size, UART_BLOCK)

def memory_specific_verify(add, file, size = 0):
    logging.info('\nStart Verify...')
    rdata = list(setup.file_read_binary(file))
    if size == 0:
        size = len(rdata)
    rdata = rdata[0:size]
    fdata = setup.flash_read(add, size)
    with io.open('memory_dump_partial.bin', 'wb') as fo:
        fo.write(bytearray(fdata))
    if (rdata == fdata):
        logging.info('memory bin comparsion PASS')
    else:
        logging.info('ERR: memory bin file comparsion error')

def memory_specific_programming(start, fw_bin):
    #logging.info('=================================================================')
    #logging.info('Memory: (Specific) Sector Erase Start')
    start = int(start,16)
    #start_idx = start // 4096
    #print('dddd =', os.path.exists(fw_bin))
    file_size = os.path.getsize(fw_bin) 
    memory_specific_bin_program(start, fw_bin, file_size)
    memory_specific_verify(start, fw_bin, file_size)

def memory_specific_get_bin(start, fw_bin):
    logging.info('=================================================================')
    logging.info('Memory: (Specific) Get / Read BIN BACK')
    start = int(start,16)
    start_idx = start // 4096
    #print('dddd =', os.path.exists(fw_bin))
    file_size = os.path.getsize(fw_bin) 
    memory_specific_verify(start, fw_bin, file_size)


if __name__ == "__main__":


    # arugment parser
    parser = argparse.ArgumentParser(epilog="See the DOC: [SDK_DOC]/KL520 DFW_Boot.pdf")
    parser.add_argument('-s', '--CHIP_INIT', action='store_true', help='Chip init', default=False)
    parser.add_argument('-r', '--RUN_SCPU_START', action='store_true', help='Change CP to specific address', default=False)
    parser.add_argument('-i', '--ADDR_INDEX', help='Set start address index', default="0")
    parser.add_argument('-p', '--MEMORY_SPECIFIC_PARTITION', help='Specific partition memory writing')
    parser.add_argument('-g', '--MEMORY_SPECIFIC_GET_BIN', help='Specific partition memory reading')

    args = parser.parse_args()

    # set log file
    logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s : %(message)s', filename='test_report.txt')
    console = logging.StreamHandler()
    console.setLevel(logging.INFO)
    logging.getLogger('').addHandler(console)

    if (args.CHIP_INIT):
        setup.dev_init(115200)
        print('Device init successfully')
        ret = setup.xmodem_send_bin()
        if(ret):
            print("Xmodem sends Minion file DONE!!!")
        else:
            print("Xmodem sends Minion file FAIL!!!")
    elif (args.RUN_SCPU_START):
        setup.dev_init(921600)
        print('Device init successfully')
        sendcmd_scpu_run(args.ADDR_INDEX)
    elif (args.MEMORY_SPECIFIC_PARTITION):
        setup.dev_init(921600)
        print('Device init successfully')
        memory_specific_programming(args.ADDR_INDEX, args.MEMORY_SPECIFIC_PARTITION)
    elif (args.MEMORY_SPECIFIC_GET_BIN):
        setup.dev_init(921600)
        memory_specific_get_bin(args.ADDR_INDEX, args.MEMORY_SPECIFIC_GET_BIN)
    else:
        parser.print_help()

