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

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

# Import standard modules
import sys
import time
import random
import math

# Import specific modules
#import rr
from csr import *

# Import register maps
from vic_regs import *

# Class to access VIC (Vectored Interrupt Controller)

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

class CVic:

    # Interrupt vector table start address offset
    IVT_ADDR = 0x80

    #======================================================================
    # Class initialisation

    def __init__(self, bus, base_address):
        self.bus = bus
        self.base_address = base_address

        # Objects declaration
        self.vic = CCSR(self.bus, self.base_address, VIC_REGS)


    def print_regs(self):
        self.vic.print_reg_map()

    def print_ivt(self):
        print "\nInterrupt vector table:"
        print "------+-------------------------------------------"
        print " vect | address"
        print "------+-------------------------------------------"
        for i in range(32):
            val = self.bus.iread(0, self.base_address + self.IVT_ADDR + (i*4), 4)
            print "   %02d | 0x%08X" % (i, val)

    def enable_module(self):
        self.vic.set_field('CTL', 'EN', 1)

    def disable_module(self):
        self.vic.set_field('CTL', 'EN', 0)

    def set_polarity(self, pol):
        self.vic.set_field('CTL', 'POL', pol)

    def enable_emu_edge(self, length=1000):
        self.vic.set_field('CTL', 'EMU_EDGE', 1)
        self.vic.set_field('CTL', 'EMU_LEN', length)

    def disable_emu_edge(self):
        self.vic.set_field('CTL', 'EMU_EDGE', 0)

    def enable_int(self, int_number):
        self.vic.set_reg('IER', 1 << int_number)

    def disbale_int(self, int_number):
        self.vic.set_reg('IDR', 1 << int_number)

    def get_raw_int_status(self):
        return self.vic.get_reg('RISR')

    def get_int_enable_mask(self):
        return self.vic.get_reg('IMR')

    def get_int_vector_addr(self):
        return self.vic.get_reg('VAR')

    def sw_int(self, int_number):
        self.vic.set_reg('SWIR',  1 << int_number)

    def int_ack(self):
        self.vic.set_reg('EOIR', 0x0)

    def get_vector_addr(self, vect):
        return self.bus.iread(0, self.base_address + self.IVT_ADDR + (vect*4), 4)

    # TODO -> set vector table with custom vector addresses


