Commit d19fe2f0 authored by Andrey Filippov's avatar Andrey Filippov
Browse files

merged x393_mem.py with the chnages in x393_sata project

parent c8777937
Loading
Loading
Loading
Loading
+70 −20
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ __status__ = "Development"
import mmap
#import sys
import struct
import os
class X393Mem(object):
    '''
    classdocs
@@ -39,11 +40,54 @@ class X393Mem(object):
    PAGE_SIZE=4096
    DEBUG_MODE=1
    ENDIAN="<" # little, ">" for big
    AXI_SLAVE0_BASE=0x40000000
    MAXI0_BASE=0x40000000
    MAXI1_BASE=0x80000000
    MAXI_BASE = MAXI0_BASE
    USE_NEGATIVE = True # Old versions of Python (2.7.3) required mmap offset to fit into 32 bits, so upper half had to be negative
                        # 2.7.11 does not need subtraction(and reports error if negative)

    def __init__(self, debug_mode=1,dry_mode=True):
    def __init__(self, debug_mode=1,dry_mode=False, maxi_port=0):
        if maxi_port:
            self.MAXI_BASE=self.MAXI1_BASE
        else:    
            self.MAXI_BASE=self.MAXI0_BASE;
        self.DEBUG_MODE=debug_mode
        if not dry_mode:
            if not os.path.exists("/dev/xdevcfg"):
                dry_mode=True
                print("Program is forced to run in SIMULATED mode as '/dev/xdevcfg' does not exist (not a camera)")
        self.DRY_MODE=dry_mode
    def maxi_base(self, maxi_port=None):
        if not maxi_port is None:
            if maxi_port:
                self.MAXI_BASE=self.MAXI1_BASE
            else:    
                self.MAXI_BASE=self.MAXI0_BASE;
        else:
            maxi_port = (0,1)[self.MAXI_BASE == self.MAXI1_BASE]
        print ("MAXI port = %d (0x%08x)"%(maxi_port, self.MAXI_BASE))       

    def wrap_mm (self, f, page_addr):
        if page_addr>=0x80000000:
            if (self.USE_NEGATIVE):
                try:
                    return mmap.mmap(f.fileno(), self.PAGE_SIZE, offset = page_addr - (1<<32))
                except:
                    self.USE_NEGATIVE = False
                    if self.DEBUG_MODE:
                        print ("Turning OFF use of negative offsets in mmap")
                    return mmap.mmap(f.fileno(), self.PAGE_SIZE, offset = page_addr)
            else:
                try:
                    return mmap.mmap(f.fileno(), self.PAGE_SIZE, offset = page_addr)
                except:
                    print ("Turning ON use of negative offsets in mmap")
                    self.USE_NEGATIVE = True
                    return mmap.mmap(f.fileno(), self.PAGE_SIZE, offset = page_addr - (1<<32))
        else:
             return mmap.mmap(f.fileno(), self.PAGE_SIZE, offset = page_addr)
         
                        
    def write_mem (self,addr, data,quiet=1):
        """
        Write 32-bit word to physical memory
@@ -57,9 +101,10 @@ class X393Mem(object):
        with open("/dev/mem", "r+b") as f:
            page_addr=addr & (~(self.PAGE_SIZE-1))
            page_offs=addr-page_addr
            mm = self.wrap_mm(f, page_addr)
#            if (page_addr>=0x80000000):
#                page_addr-= (1<<32)
            mm = mmap.mmap(f.fileno(), self.PAGE_SIZE, offset=page_addr)
#            mm = mmap.mmap(f.fileno(), self.PAGE_SIZE, offset=page_addr)
            packedData=struct.pack(self.ENDIAN+"L",data)
            d=struct.unpack(self.ENDIAN+"L",packedData)[0]
            mm[page_offs:page_offs+4]=packedData
@@ -87,9 +132,10 @@ class X393Mem(object):
        with open("/dev/mem", "r+b") as f:
            page_addr=addr & (~(self.PAGE_SIZE-1))
            page_offs=addr-page_addr
            mm = self.wrap_mm(f, page_addr)
#            if (page_addr>=0x80000000):
#                page_addr-= (1<<32)
            mm = mmap.mmap(f.fileno(), self.PAGE_SIZE, offset=page_addr)
#            mm = mmap.mmap(f.fileno(), self.PAGE_SIZE, offset=page_addr)
            data=struct.unpack(self.ENDIAN+"L",mm[page_offs:page_offs+4])
            d=data[0]
            if quiet < 1:
@@ -128,9 +174,10 @@ class X393Mem(object):
                for addr in range (start_addr,end_addr+byte_mode,byte_mode):
                    page_addr=addr & (~(self.PAGE_SIZE-1))
                    page_offs=addr-page_addr
                    mm = self.wrap_mm(f, page_addr)
        #            if (page_addr>=0x80000000):
        #                page_addr-= (1<<32)
                    mm = mmap.mmap(f.fileno(), self.PAGE_SIZE, offset=page_addr)
        #            mm = mmap.mmap(f.fileno(), self.PAGE_SIZE, offset=page_addr)
                    data=struct.unpack_from(self.ENDIAN+frmt_bytes[byte_mode],mm, page_offs)
                    rslt.append(data[0])
                    
@@ -181,9 +228,10 @@ class X393Mem(object):
                if page_num == last_page:
                    end_offset = start_addr + length - self.PAGE_SIZE * page_num
                page_addr = page_num * self.PAGE_SIZE 
                mm = self.wrap_mm(f, page_addr)
    #            if (page_addr>=0x80000000):
    #                page_addr-= (1<<32)
                mm = mmap.mmap(f.fileno(), self.PAGE_SIZE, offset=page_addr)
    #            mm = mmap.mmap(f.fileno(), self.PAGE_SIZE, offset=page_addr)
                bf.write(mm[start_offset:end_offset])

    def mem_clear (self, start_addr, length, word32):
@@ -208,9 +256,10 @@ class X393Mem(object):
                if page_num == last_page:
                    end_offset = start_addr + length - self.PAGE_SIZE * page_num
                page_addr = page_num * self.PAGE_SIZE 
                mm = self.wrap_mm(f, page_addr)
    #            if (page_addr>=0x80000000):
    #                page_addr-= (1<<32)
                mm = mmap.mmap(f.fileno(), self.PAGE_SIZE, offset=page_addr)
    #            mm = mmap.mmap(f.fileno(), self.PAGE_SIZE, offset=page_addr)
                mm[start_offset:end_offset] = patt[start_offset:end_offset]


@@ -243,8 +292,8 @@ class X393Mem(object):
                data = (start_data + ((addr-start_addr) // byte_mode)*inc_data) & data_mask
                page_addr=addr & (~(self.PAGE_SIZE-1))
                page_offs=addr-page_addr
#                if (page_addr>=0x80000000):
#                    page_addr-= (1<<32)
                if (page_addr>=0x80000000):
                    page_addr-= (1<<32)
                print (("0x%08x: "+ data_frmt)%(addr,data))
        else:
            with open("/dev/mem", "r+b") as f:
@@ -252,9 +301,10 @@ class X393Mem(object):
                    data = (start_data + ((addr-start_addr) // byte_mode)*inc_data) & data_mask
                    page_addr=addr & (~(self.PAGE_SIZE-1))
                    page_offs=addr-page_addr
                    mm = self.wrap_mm(f, page_addr)
        #            if (page_addr>=0x80000000):
        #                page_addr-= (1<<32)
                    mm = mmap.mmap(f.fileno(), self.PAGE_SIZE, offset=page_addr)
        #            mm = mmap.mmap(f.fileno(), self.PAGE_SIZE, offset=page_addr)
                    struct.pack_into(self.ENDIAN+frmt_bytes[byte_mode],mm, page_offs, data)
    
    '''
@@ -266,14 +316,14 @@ class X393Mem(object):
        <addr> - physical byte address relative to the slave AXI memory region
        <data> - 32-bit data to write
        """
        self.write_mem(self.AXI_SLAVE0_BASE+addr,data)
        self.write_mem(self.MAXI_BASE+addr,data)

    def axi_read_addr(self,addr):
        """
        Read 32-bit word from the  slave AXI address range
        <addr> - physical byte address relative to slave AXI AXI memory region
        """
        return self.read_mem(self.AXI_SLAVE0_BASE+addr)
        return self.read_mem(self.MAXI_BASE+addr)
    '''
    Read/write slave AXI using 32-bit word addresses (same as in Verilog code)
    '''