#!/usr/bin/python
#coding: utf8

# Copyright CERN, 2011 - 2013 (INCAA Computers BV)
# Author: Samuel Iglesias Gonsalvez <siglesia@cern.ch>
# Author: INCAA Computers BV (info@incaacomputers.com)
# Licence: GPL v2 or later.
# Website: http://www.ohwr.org
# Website: http://www.incaacomputers.com
# Version: 2.0 (Last modifications: 13/06/2013)
#
# FPGA firmware: spec_pts_flash.bin
#
# Description
#  This test loads a firmware file to Flash memory and boots the FPGA from it.
#  The firmware is just to test the Push-Buttons and LEDs of the SPEC board.
#  This test needs the operator's intervention; when prompted the operator needs to
#  press the two Push-Buttons of the SPEC under test and check the four LEDs on the
#  board and the two LEDs in the front.

import sys
import rr
import time
import os
import os.path
from ctypes import *
from ptsexcept import *
sys.path.append('sdbfs')
import gen_flash_image

"""
test03: loads a firmware file to Flash memory and boots from it. The FW just blinks the leds.
"""

mac_filename = 'mac.tmp'

##-------------------------------------------------------------------------------------------------
##                                       Gennum Flash class                                      --
##-------------------------------------------------------------------------------------------------

class CGennumFlash :
    GENNUM_FLASH = 1;
    GENNUM_FPGA = 2;
    FPGA_FLASH = 3; 

    def __init__ (self, bus, path):
        self.bus = bus;
        library = os.path.join(path,"libfpga_loader.so");
        self.lib = cdll.LoadLibrary(library);
        self.lib.rr_init();
        self.lib.gpio_init();

##-------------------------------------------------------------------------------------------------
##                                             main                                              --
##-------------------------------------------------------------------------------------------------

def main (default_directory='.'):

    path_firmware = '../firmwares/spec_pts_flash.bin';
    # first try to read MAC address form file
    filename = os.path.join(default_directory, mac_filename)
    print "Trying to open " + filename
    try:
        macfile = open(filename, 'r')
    except IOError:
        print "MAC address not assigned..."
        mac = ""
    else:
        mac = macfile.read()
        macfile.close()
        os.remove(filename)
        print "MAC: " + mac

        gen_flash_image.gen_sdb_image("spec", mac,
                default_directory+"/../firmwares/spec_pts_flash.bin",
                default_directory+"/test_flash_mac.bin")
        path_firmware = default_directory+"/test_flash_mac.bin"

    # Load board library and open the corresponding device
    print "Loading hardware access library and opening devices\n"
    spec = rr.Gennum();
    flash = CGennumFlash(spec, default_directory);

    print "Test03 Start"
    init_test_time = time.time()
    ret_error = None

    start = time.time();
    flash.lib.gpio_bootselect(flash.GENNUM_FLASH);
    version = hex(flash.lib.flash_read_id());
    #if (version != "0x202016"):
    # added the version for the new parts M25P64-VMF6TP and W25Q64JVSFIQ:
    if (version != "0x202016" and version != "0x202017" and version != "0xef4017"):
        raise PtsError('Error: version of the flash is not correct: ' + version);
    
    # Load a new firmware to the Flash memory.
    print "Starting the process to load a FW into Flash memory"
    flash.lib.load_mcs_to_flash(path_firmware);

    time.sleep(1);
    print "Forcing to load FW from Flash memory to FPGA"

    # Force the FPGA to load the FW from the Flash memory

    flash.lib.force_load_fpga_from_flash();
    
    finish = time.time();

    print "Time elapsed: " + str(finish - start) + " seconds" 

    time.sleep(5)

    ask = "";
    tmp_stdout = sys.stdout;
    sys.stdout = sys.__stdout__;
    tmp_stdin = sys.stdin;
    sys.stdin = sys.__stdin__;
    while ((ask != "Y") and (ask != "N")) :
        print "-------------------------------------------------------------"
        print "\t PRESS THE BUTTONS IN THE SPEC BOARD "
        print "-------------------------------------------------------------"
        ask = raw_input("Are the LEDs blinking when you press the buttons? [Y/N]")
        ask = ask.upper()

    sys.stdout = tmp_stdout;
    sys.stdin = tmp_stdin;
    if (ask == "N") :
        ret_error = "Error loading FW through the Flash memory or there is a problem with the LEDs";

    end_test_time = time.time()
    print "End of Test03"
    print "RESULT: [{}]".format("FAIL" if ret_error else "OK")
    print 'Test03 elapsed time: {:.2f} seconds'.format(end_test_time-init_test_time)
    if ret_error:
        raise PtsError(ret_error)

if __name__ == '__main__' :
    main();
