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

implemented help for task based on functions documentation

parent e6868ded
Loading
Loading
Loading
Loading
+56 −17
Original line number Diff line number Diff line
@@ -35,7 +35,9 @@ __status__ = "Development"
'''
import sys
import os

import inspect
import re
#import os.path
from argparse import ArgumentParser
#import argparse
from argparse import RawDescriptionHelpFormatter
@@ -78,8 +80,12 @@ class CLIError(Exception):
def extractTasks(obj,inst):
    for name in obj.__dict__:
        if hasattr((obj.__dict__[name]), '__call__') and not (name[0]=='_'):
#            print (name+" -->"+str(obj.__dict__[name]))
#            print (obj.__dict__[name].func_code)
#            print ("COMMENTS:"+str(inspect.getcomments(obj.__dict__[name])))
#            print ("DOCS:"+str(inspect.getdoc(obj.__dict__[name])))
            func_args=obj.__dict__[name].func_code.co_varnames[1:obj.__dict__[name].func_code.co_argcount]
            callableTasks[name]={'func':obj.__dict__[name],'args':func_args,'inst':inst}
            callableTasks[name]={'func':obj.__dict__[name],'args':func_args,'inst':inst,'docs':inspect.getdoc(obj.__dict__[name])}
def execTask(commandLine):
#    result=None
    cmdList=commandLine #.split()
@@ -118,6 +124,17 @@ def hx(obj):
        return "0x%x"%obj
    except:
        return str(obj)

def getFuncArgsString(name):
    funcFArgs=callableTasks[name]['args']
    sFuncArgs=""
    if funcFArgs:
        sFuncArgs+='<'+str(funcFArgs[0])+'>'
        for a in funcFArgs[1:]:
            sFuncArgs+=' <'+str(a)+'>'
    return sFuncArgs

    
def main(argv=None): # IGNORE:C0111
    '''Command line options.'''

@@ -163,9 +180,14 @@ USAGE
        parser.add_argument("-p", "--parameter",  dest="parameters", action="append", default=[], help="Define parameter(s) as name=value" , nargs='*' )
        parser.add_argument("-c", "--command",  dest="commands", action="append", default=[], help="execute command" , nargs='*')
        parser.add_argument("-i", "--interactive", dest="interactive", action="store_true", help="enter interactive mode [default: %(default)s]")
        parser.add_argument("-s", "--simulated", dest="simulated", action="store_true", help="Simulated mode (no real hardware I/O) [default: %(default)s]")

        # Process arguments
        args = parser.parse_args()
        if not args.simulated:
            if not os.path.isfile("/dev/xdevcfg"):
                args.simulated=True
                print("Program is forced to run in SIMULATED mode as '/dev/xdevcfg' does not exist (not a camera)")
        #print("--- defines=%s"%    str(args.defines))
        #print("--- paths=%s"%      str(args.paths))
        #print("--- parameters=%s"% str(args.parameters))
@@ -259,12 +281,12 @@ USAGE
    if verbose > 3: print("vpars1.VERBOSE__TYPE="+str(vpars1.VERBOSE__TYPE))
    if verbose > 3: print("vpars1.VERBOSE__RAW="+str(vpars1.VERBOSE__RAW))
    
    x393mem=    x393_mem.X393Mem(verbose,True) #add dry run parameter
    x393tasks=  x393_axi_control_status.X393AxiControlStatus(verbose,True)
    x393Pio=    x393_pio_sequences.X393PIOSequences(verbose,True)
    x393Timing= x393_mcntrl_timing.X393McntrlTiming(verbose,True)
    x393Buffers=x393_mcntrl_buffers.X393McntrlBuffers(verbose,True)
    x393Tests=  x393_mcntrl_tests.X393McntrlTests(verbose,True)
    x393mem=    x393_mem.X393Mem(verbose,args.simulated) #add dry run parameter
    x393tasks=  x393_axi_control_status.X393AxiControlStatus(verbose,args.simulated)
    x393Pio=    x393_pio_sequences.X393PIOSequences(verbose,args.simulated)
    x393Timing= x393_mcntrl_timing.X393McntrlTiming(verbose,args.simulated)
    x393Buffers=x393_mcntrl_buffers.X393McntrlBuffers(verbose,args.simulated)
    x393Tests=  x393_mcntrl_tests.X393McntrlTests(verbose,args.simulated)
    '''
    print ("----------------------")
    print("x393_mem.__dict__="+str(x393_mem.__dict__))
@@ -315,23 +337,40 @@ USAGE
    if (args.interactive):
        line =""
        while True:
            line=raw_input('x393--> ').strip()
            line=raw_input('x393%s--> '%('','(simulated)')[args.simulated]).strip()
            if not line:
                print ('Use "quit" to exit, "help" - for help')
            elif line == 'quit':
            elif (line == 'quit') or (line == 'exit'):
                break
            elif line== 'help' :
                print ("\nAvailable tasks:")
                for name,val in sorted(callableTasks.items()):
#                    funcFArgs=callableTasks[name]['args']
                    funcFArgs=val['args']
                    sFuncArgs=""
                    if funcFArgs:
                        sFuncArgs+='<'+str(funcFArgs[0])+'>'
                        for a in funcFArgs[1:]:
                            sFuncArgs+=' <'+str(a)+'>'
                    sFuncArgs=getFuncArgsString(name)
                    print ("Usage: %s %s"%(name,sFuncArgs))
                print ('\n"parameters" and "defines" list known defined parameters and macros')
            elif (len(line) > len("help")) and (line[:len("help")]=='help'):
                helpFilter=line[len('help'):].strip()
                try:
                    re.match(helpFilter,"")
                except:
                    print("Invalid search expression: %s"%helpFilter)
                    helpFilter=None    
                if helpFilter:
                    print
                    for name,val in sorted(callableTasks.items()):
#                       if re.findall(helpFilter,name):
                        if re.match(helpFilter,name):
                            print('=== %s ==='%name)
                            sFuncArgs=getFuncArgsString(name)
#                           print ("Usage: %s %s"%(name,sFuncArgs))
                            docs=callableTasks[name]['docs']
                            if docs:
                                docsl=docs.split("\n")
                                for l in docsl:
                                    #print ('    %s'%l)
                                    print ('%s'%l)
                                    #print(docs)
                            print ("     Usage: %s %s\n"%(name,sFuncArgs))
            elif line == 'parameters':
                parameters=ivp.getParameters()
                for par,val in sorted(parameters.items()):
+81 −7
Original line number Diff line number Diff line
@@ -65,8 +65,17 @@ class X393AxiControlStatus(object):
        '''
        
    def write_contol_register(self, reg_addr, data):
        """
        Write 32-bit word to the control register
        <addr> - register address relative to the control register address space
        <data> - 32-bit data to write
        """
        self.x393_mem.axi_write_single_w(self.CONTROL_ADDR+reg_addr, data)
    def read_and_wait_status(self, address):
        """
        Read word from the status register (up to 26 bits payload and 6-bit sequence number)
        <addr> - status register address (currently 0..255)
        """
        return self.x393_mem.axi_read_addr_w(self.STATUS_ADDR + address )
    
    def wait_status_condition(self,
@@ -77,6 +86,20 @@ class X393AxiControlStatus(object):
                              mask,                   # input [25:0] mask;           // which bits to compare
                              invert_match,           # input        invert_match;   // 0 - wait until match to pattern (all bits), 1 - wait until no match (any of bits differ)
                              wait_seq):              # input        wait_seq; // Wait for the correct sequence number, False assume correct
        """
        Poll specified status register until some condition is matched
        <status_address> -         status register address (currently 0..255)
        <status_control_address> - control register address (to control status generation)
        <status_mode>            - status generation mode:
                                  0: disable status generation,
                                  1: single status request,
                                  2: auto status, keep specified seq number,
                                  4: auto, inc sequence number 
        <pattern> -                26-bit pattern to match
        <mask> -                   26-bit mask to enable pattern matching (0-s - ignore)
        <invert_match> -           invert match (wait until matching condition becomes false)
        <wait_seq>-                wait for the correct sequence number, if False - assume always correct
        """
        match=False
        while not match:
            data=self.read_and_wait_status(status_address)
@@ -92,6 +115,9 @@ class X393AxiControlStatus(object):
            if self.DRY_MODE: break

    def read_all_status(self):
        """
        Read and print contents of all defined status registers
        """
#        print (self.__dict__)
#        for name in self.__dict__:
#            print (name+": "+str(name=='MCONTR_PHY_STATUS_REG_ADDR'))
@@ -113,19 +139,33 @@ class X393AxiControlStatus(object):
                       reg_addr,    # input  [7:0] reg_addr;
                       mode,        # input  [1:0] mode;
                       seq_number): # input  [5:0] seq_number;
        '''
 // mode bits:
 // 0 disable status generation,
 // 1 single status request,
 // 2 - auto status, keep specified seq number,
 // 3 - auto, inc sequence number
         '''
        """
        Poll specified status register until some condition is matched
        <base_addr> -  base control address of the selected module
        <reg_addr> -   status control register relative to the module address space
        <mode> -       status generation mode:
                                  0: disable status generation,
                                  1: single status request,
                                  2: auto status, keep specified seq number,
                                  4: auto, inc sequence number 
        <seq_number> - 6-bit sequence number of the status message to be sent
        """
        self.write_contol_register(base_addr + reg_addr, ((mode & 3)<< 6) | (seq_number * 0x3f))


    def program_status_all( self,
                            mode,     # input [1:0] mode;
                            seq_num): # input [5:0] seq_num;
        """
        Set status generation mode for all defined modules
        <mode> -       status generation mode:
                                  0: disable status generation,
                                  1: single status request,
                                  2: auto status, keep specified seq number,
                                  4: auto, inc sequence number 
        <seq_number> - 6-bit sequence number of the status message to be sent
        """

        self.program_status (self.MCONTR_PHY_16BIT_ADDR,     self.MCONTR_PHY_STATUS_CNTRL,        mode,seq_num)# //MCONTR_PHY_STATUS_REG_ADDR=          'h0,
        self.program_status (self.MCONTR_TOP_16BIT_ADDR,     self.MCONTR_TOP_16BIT_STATUS_CNTRL,  mode,seq_num)# //MCONTR_TOP_STATUS_REG_ADDR=          'h1,
        self.program_status (self.MCNTRL_PS_ADDR,            self.MCNTRL_PS_STATUS_CNTRL,         mode,seq_num)# //MCNTRL_PS_STATUS_REG_ADDR=           'h2,
@@ -140,32 +180,61 @@ class X393AxiControlStatus(object):
        
    def enable_cmda(self,
                    en): # input en;
        """
        Enable (disable) address, bank and command lines to the DDR3 memory
        <en> - 1 - enable, 0 - disable
        """
        self.write_contol_register(self.MCONTR_PHY_0BIT_ADDR +  self.MCONTR_PHY_0BIT_CMDA_EN + en, 0);
            
    def enable_cke(self,
                    en): # input en;
        """
        Enable (disable) CKE - clock enable to DDR3 memory 
        <en> - 1 - enable, 0 - disable
        """
        self.write_contol_register(self.MCONTR_PHY_0BIT_ADDR +  self.MCONTR_PHY_0BIT_CKE_EN + en, 0);

    def activate_sdrst(self,
                    en): # input en;
        """
        Activate SDRST (reset) to DDR3 memory 
        <en> - 1 - activate (low), 0 - deactivate (high)
        """
        self.write_contol_register(self.MCONTR_PHY_0BIT_ADDR +  self.MCONTR_PHY_0BIT_SDRST_ACT + en, 0);

    def enable_refresh(self,
                    en): # input en;
        """
        Enable (disable) refresh of the DDR3 memory 
        <en> - 1 - enable, 0 - disable
        """
        self.write_contol_register(self.MCONTR_TOP_0BIT_ADDR +  self.MCONTR_TOP_0BIT_REFRESH_EN + en, 0);
        
    def enable_memcntrl(self,
                    en): # input en;
        """
        Enable memory controller module 
        <en> - 1 - enable, 0 - disable
        """
        self.write_contol_register(self.MCONTR_TOP_0BIT_ADDR +  self.MCONTR_TOP_0BIT_MCONTR_EN + en, 0);
        
    def enable_memcntrl_channels(self,
                                 chnen): # input [15:0] chnen; // bit-per-channel, 1 - enable;
        """
        Enable memory controller channels (all at once control) 
        <chnen> - 16-bit control word with per-channel enable bits (bit0 - chn0, ... bit15 - chn15)
        """
        self.enabled_channels = chnen; # currently enabled memory channels
        self.write_contol_register(self.MCONTR_TOP_16BIT_ADDR +  self.MCONTR_TOP_16BIT_CHN_EN, self.enabled_channels & 0xffff) # {16'b0,chnen});

    def enable_memcntrl_en_dis(self,
                               chn, # input [3:0] chn;
                               en):# input       en;
        """
        Enable memory controller channels (one at a time) 
        <chn> - 4-bit channel select
        <en> -  1 - enable, 0 - disable of the selected channel
        """
        if en:
            self.enabled_channels = self.enabled_channels | (1<<chn);
        else:
@@ -175,5 +244,10 @@ class X393AxiControlStatus(object):
    def configure_channel_priority(self,
                                   chn, # input [ 3:0] chn;
                                   priority): #input [15:0] priority; // (higher is more important)
        """
        Configure channel priority  
        <chn> -      4-bit channel select
        <priority> - 16-bit priority value (higher value means more important)
        """
        self.write_contol_register(self.MCONTR_ARBIT_ADDR + chn, priority  & 0xffff)# {16'b0,priority});
+41 −1
Original line number Diff line number Diff line
@@ -61,6 +61,15 @@ class X393McntrlBuffers(object):
                                 num_bursts, # input [NUM_XFER_BITS:0] num_bursts; // number of 8-bursts to write (will be rounded up to multiple of 16)
                                 startX,     # input integer startX;
                                 startY):    #input integer startY;
        """
        Fill buffer with the generated data in scanline mode
        <chn>        4-bit channel number (0,1,2,3,4 are valid) to use
        <page>       2-bit page number in the buffer to write to
        <num_bursts> number of 8-word (16 bytes) bursts to write
        <startX>     horizontal shift of the left of the data line to write, in bytes
        <startY>     line number to encode in the data
        """
        if self.DEBUG_MODE > 1:
            print("====== write_block_scanline_chn:%d page: %x X=0x%x Y=0x%x num=%dt"%(chn, page, startX, startY,num_bursts))
        if   chn == 0:  start_addr=self.MCONTR_BUF0_WR_ADDR + (page << 8)
        elif chn == 1:  start_addr=self.MCONTR_BUF1_WR_ADDR + (page << 8)
@@ -76,6 +85,11 @@ class X393McntrlBuffers(object):
    def write_block_buf(self,
                              start_word_address, # input [29:0] start_word_address;
                              num_words_or_data_list):          # input integer num_words; # number of words to write (will be rounded up to multiple of 16)
        """
        Fill buffer the pattern data
        <start_word_address>     full register address in AXI space (in 32-bit words, not bytes)
        <num_words_or_data_list> number of 32-bit words to generate/write or a list with integer data
        """
        if isinstance (num_words_or_data_list,int):
            data=[]
            for i in range(num_words_or_data_list):
@@ -94,6 +108,12 @@ class X393McntrlBuffers(object):
                              start_word_address, # input [29:0] start_word_address;
                              num_words,          # input integer num_words; # number of words to write (will be rounded up to multiple of 16)
                              start_value):       # input integer start_value;      
        """
        Fill buffer the incremental data (each next register is written with previous register data + 1
        <start_word_address>  full register address in AXI space (in 32-bit words, not bytes)
        <num_words>           number of 32-bit words to generate/write
        <start_value>         value to write to the first register (to start_word_address)
        """
        if self.verbose>0:
            print("**** write_block_incremtal, start_word_address=0x%x, num_words=0x%x, start_value=0x%x "%(start_word_address,num_words,start_value))
        for i in range(0,num_words):
@@ -105,6 +125,12 @@ class X393McntrlBuffers(object):
                            chn,        # input integer chn; # buffer channel
                            page,       # input   [1:0] page;
                            num_words_or_data_list): # input integer num_words; # number of words to write (will be rounded up to multiple of 16)
        """
        Fill specified buffer with the pattern data
        <chn>                    4-bit buffer channel (0..4) to write data to
        <page>                   2-bit buffer page to write to
        <num_words_or_data_list> number of 32-bit words to generate/write or a list with integer data
        """
        start_addr=-1
        if   chn==0:start_addr=self.MCONTR_BUF0_WR_ADDR + (page << 8)
        elif chn==1:start_addr=self.MCONTR_BUF1_WR_ADDR + (page << 8)
@@ -120,6 +146,13 @@ class X393McntrlBuffers(object):
                       start_word_address, # input [29:0] start_word_address;
                       num_read,           # input integer num_read; # number of words to read (will be rounded up to multiple of 16)
                       show_rslt=True):
        """
        Fill buffer the incremental data (each next register is written with previous register data + 1
        <start_word_address> full register address in AXI space (in 32-bit words, not bytes)
        <num_read>           number of 32-bit words to read
        <show_rslt>          print buffer data read
        """
        
        if self.verbose>0:
            print("**** read_block_buf, start_word_address=0x%x, num_read=0x%x "%(start_word_address,num_read))
        result=[]    
@@ -135,6 +168,13 @@ class X393McntrlBuffers(object):
                           page, #input   [1:0] page;
                           num_read, #input integer num_read; # number of words to read (will be rounded up to multiple of 16)
                           show_rslt=True):
        """
        Fill buffer the incremental data (each next register is written with previous register data + 1
        <chn>                4-bit buffer channel (0..4) to read from
        <page>               2-bit buffer page to read from
        <num_read>           number of 32-bit words to read
        <show_rslt>          print buffer data read
        """
        start_addr=-1
        if   chn==0:  start_addr=self.MCONTR_BUF0_RD_ADDR + (page << 8)
        elif chn==1:  start_addr=self.MCONTR_BUF1_RD_ADDR + (page << 8)
+118 −10

File changed.

Preview size limit exceeded, changes collapsed.

+99 −12

File changed.

Preview size limit exceeded, changes collapsed.

Loading