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

# Copyright CERN, 2014
# Author: Matthieu Cattin (CERN)
# Licence: GPL v2 or later.
# Website: http://www.ohwr.org
# Last modifications: 6/11/2014

# Import standard modules
import os
import sys

# Add common modules and libraries location to path
cdir = os.path.dirname(os.path.realpath(__file__))
sys.path.append(os.path.join(cdir,'../pts/'))
sys.path.append(os.path.join(cdir,'../pts/gnurabbit/python/'))
sys.path.append(os.path.join(cdir,'../pts/common/'))

# Import specific modules
from sdb import *
from csr import *
from gn4124 import *

# Import register maps
from fmc_masterfip_proto_regs import *


# Class to access MasterFip prototype core (simple register map to send receive variables)

class FmcMasterFipProtoOperationError(Exception):
    def __init__(self, msg):
        self.msg = msg
    def __str__(self):
        return ("FmcMasterFipProto: %s" %(self.msg))

class CFmcMasterFipProto:

    REGS_ADDR = 0x11000


    def __init__(self, bus, offset=0x40000):

        self.bus = bus
        self.mezz_offset = offset

        try:
            self.regs = CCSR(self.bus, self.mezz_offset + self.REGS_ADDR, FMC_MASTERFIP_PROTO_REGS)

        except (CSRDeviceOperationError) as e:
            raise FmcMasterFipProtoOperationError(e)

    def set_core_config(self, ident_addr, cons_addr, nb_bourr):
        self.regs.set_reg(IDENT_ID_DAT_SUB, ident_addr)
        self.regs.set_reg(CONS_ID_DAT_SUB, cons_addr)
        self.regs.set_field(CONFIG, NUM_OF_BOURR, nb_bourr)

    def print_core_config(self):
        self.regs.print_reg_map()

    def continuous_loop_enable(self):
        self.regs.set_field(CONFIG, CONT_LOOP, 1)

    def continuous_loop_disable(self):
        self.regs.set_field(CONFIG, CONT_LOOP, 0)

    def start_loop(self):
        self.regs.set_field(CTRL, ACTIV_LOOP, 1)

    def stop_loop(self):
        self.regs.set_field(CTRL, ACTIV_LOOP, 0)

    # send 16-bit consumed RP_DAT
    def send_cons_rp_dat(self, data):
        self.regs.set_reg(CONSU_RP_DAT_BYTE0, (data & 0xFF))
        self.regs.set_reg(CONSU_RP_DAT_BYTE1, ((data >> 8) & 0xFF))

    def print_ident_rp_dat(self):
        for i,addr in enumerate(range(0x10, 0x38, 0x4)):
            print "Identification: byte %d: 0x%02X"%(i, self.regs.rd_reg(addr))
