x393_export_c.py 192 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
from __future__ import division
from __future__ import print_function

'''
# Copyright (C) 2015, Elphel.inc.
# Class to export hardware definitions from Verilog parameters  
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http:#www.gnu.org/licenses/>.

@author:     Andrey Filippov
@copyright:  2015 Elphel, Inc.
@license:    GPLv3.0+
@contact:    andrey@elphel.coml
@deffield    updated: Updated
'''
__author__ = "Andrey Filippov"
__copyright__ = "Copyright 2015, Elphel, Inc."
__license__ = "GPL"
__version__ = "3.0+"
__maintainer__ = "Andrey Filippov"
__email__ = "andrey@elphel.com"
__status__ = "Development"
#import sys
#import pickle
35 36 37
import os
import errno
import datetime
38 39
import vrlg
class X393ExportC(object):
40 41 42 43 44 45 46 47
    DRY_MODE =    True # True
    DEBUG_MODE =  1
    MAXI0_BASE =  0x40000000
    MAXI0_RANGE = 0x00003000
    verbose =     1
    func_decl =   None
    func_def =    None
    typedefs =    None
48 49 50 51 52 53 54
    gen_dir =       "generated"
    typdefs_file =  "x393_types.h" # typdef for hardware registers
    header_file =   "x393.h"       # constant definitions and function declarations
    func_def_file = "x393.c"       # functions definitions
    defs_file =     "x393_defs.h"  # alternative - constants and address definitions
    map_file =      "x393_map.h"   # address map as  defines
    
55 56 57 58 59 60 61 62 63
    dflt_frmt_spcs={'ftype':        'u32',
                    'showBits':     True,
                    'showDefaults': True,
                    'showReserved': False,
                    'nameLength':   15,
                    'lastPad':      False,
                    'macroNameLen': 48,
                    'showType':     True,
                    'showRange':    True,
64
                    'nameMembers':  False, # True, #name each struct in a union
65
                    'data32':       'd32', #union branch that is always u32 ("" to disable)
66 67 68 69 70 71 72 73
#                    'declare':(26,48,0, 80),  #function name, arguments, (body), comments
#                    'define': (26,48,72,106), #function name, arguments, body, comments
#                    'declare':(29,59,0, 91),  #function name, arguments, (body), comments
#                    'define': (29,59,83,117), #function name, arguments, body, comments
#                    'declare':(29,59,0, 103),  #function name, arguments, (body), comments
#                    'define': (29,59,83,127), #function name, arguments, body, comments
                    'declare':(29,65,0, 113),  #function name, arguments, (body), comments
                    'define': (29,65,85,130), #function name, arguments, body, comments
74
                    'body_prefix':'\n    '    #insert before function body {}
75 76
                    
                    } 
77 78 79 80 81 82 83 84

    def __init__(self, debug_mode=1,dry_mode=True, saveFileName=None):
        self.DEBUG_MODE=  debug_mode
        self.DRY_MODE=    dry_mode
        try:
            self.verbose=vrlg.VERBOSE
        except:
            pass
85
        
86
    def export_all(self):
87 88 89 90 91 92 93 94 95
        self.func_decl=[]
        self.func_def= []
        self.save_typedefs(self.gen_dir, self.typdefs_file)
        
        
        self.save_header_file      (self.gen_dir, self.header_file)
        self.save_func_def_file    (self.gen_dir, self.func_def_file)
        self.save_defines_file     (self.gen_dir, self.defs_file)
        self.save_harware_map_file (self.gen_dir, self.map_file)
96 97
        return "OK"
    
98 99 100 101 102 103 104 105 106
    def make_generated(self, path):
        try:
            os.makedirs(path)
        except OSError as exception:
            if exception.errno != errno.EEXIST:
                raise
            
    def generated_fileHeader(self, filename, description):
        header_template="""/*******************************************************************************
107 108 109 110
 * @file %s
 * @date %s  
 * @author auto-generated file, see %s
 * @brief %s
111
 *******************************************************************************/"""
112 113 114 115
        script_name = os.path.basename(__file__)
        if script_name[-1] == "c":
            script_name = script_name[:-1] 
        return header_template%(filename, datetime.date.today().isoformat(), script_name, description)
116 117 118 119 120 121
    def gen_ifdef(self,filename):
        macro= filename.upper().replace('.','_')
        return """#ifndef %s
#define %s        
"""%(macro,macro)
        return
122 123 124 125 126 127 128 129
        
    def save_typedefs(self, directory, filename):
        description = 'typedef definitions for the x393 hardware registers'
        header = self.generated_fileHeader(filename,description)
        txt=self.get_typedefs(frmt_spcs = None)
        self.make_generated(os.path.abspath(os.path.join(os.path.dirname(__file__), directory)))
        with open(os.path.abspath(os.path.join(os.path.dirname(__file__), directory, filename)),"w") as out_file:
            print(header,file=out_file)
130
            print(self.gen_ifdef(filename),file=out_file)
131
            print(txt,file=out_file)
132
            print("#endif",file=out_file)
133 134 135 136 137
        print ("%s are written to  to %s"%(description, os.path.abspath(os.path.join(os.path.dirname(__file__), directory, filename))))
        
    def save_header_file(self, directory, filename):
        description = 'Constants definitions and functions declarations to access x393 hardware registers'
        header = self.generated_fileHeader(filename,description)
138 139
        ld= self.define_macros()
        ld+=self.define_other_macros()
140
        # Includes section
141
        txt = '\n#include "x393_types.h"\n'
142
        txt +='//#include "elphel/x393_defs.h // alternative variant"\n\n'
143
        txt +='// See elphel/x393_map.h for the ordered list of all I/O register addresses used\n'
144 145
        txt +=  '// init_mmio_ptr() should be called once before using any of the other declared functions\n\n'
        txt +=  'int init_mmio_ptr(void);\n'
146
        txt += '#ifndef PARS_FRAMES\n'
Andrey Filippov's avatar
Andrey Filippov committed
147 148
        txt += '    #define PARS_FRAMES       16             ///< Number of frames in a sequencer     TODO:// move it here from <uapi/elphel/c313a.h>\n'
        txt += '    #define PARS_FRAMES_MASK (PARS_FRAMES-1) ///< Maximal frame number (15 for NC393) TODO:// move it here from <uapi/elphel/c313a.h>\n'
149
        txt += '#endif\n'
150
        txt += 'typedef enum {TABLE_TYPE_QUANT,TABLE_TYPE_CORING,TABLE_TYPE_FOCUS,TABLE_TYPE_HUFFMAN} x393cmprs_tables_t; ///< compressor table type\n'
151
        txt += 'typedef enum {DIRECT,ABSOLUTE,RELATIVE,ASAP} x393cmd_t; ///< How to apply command - directly or through the command sequencer\n'
152 153 154 155 156 157
        txt += """// IRQ commands applicable to several targets
#define X393_IRQ_NOP     0 
#define X393_IRQ_RESET   1
#define X393_IRQ_DISABLE 2
#define X393_IRQ_ENABLE  3
"""        
158
        for d in ld:
159 160 161 162 163 164
            fd=self.expand_define_maxi0(d, mode = "func_decl",frmt_spcs = None)
            if fd:
                txt += fd + "\n"
        self.make_generated(os.path.abspath(os.path.join(os.path.dirname(__file__), directory)))
        with open(os.path.abspath(os.path.join(os.path.dirname(__file__), directory, filename)),"w") as out_file:
            print(header,file=out_file)
165
            print(self.gen_ifdef(filename),file=out_file)
166
            print(txt,file=out_file)
167 168
            print("#endif",file=out_file)
            
169 170 171 172 173 174 175
        print ("%s are written to  to %s"%(description, os.path.abspath(os.path.join(os.path.dirname(__file__), directory, filename))))
        
    def save_func_def_file(self, directory, filename):
        description = 'Functions definitions to access x393 hardware registers'
        header = self.generated_fileHeader(filename,description)
        ld= self.define_macros()
        ld+=self.define_other_macros()
176
        # Includes section
177 178
        txt  = '\n#include <linux/io.h>\n'
        txt += '#include <linux/spinlock.h>\n'
179
        txt +=  '#include "x393.h"\n\n'
Andrey Filippov's avatar
Andrey Filippov committed
180
        txt +=  'static void __iomem* mmio_ptr;\n\n'
181
        txt +=  'static DEFINE_SPINLOCK(lock);\n\n'
182 183
        txt +=  '// init_mmio_ptr() should be called once before using any of the other defined functions\n\n'
        txt +=  'int init_mmio_ptr(void) {mmio_ptr = ioremap(0x%08x, 0x%08x); if (!mmio_ptr) return -1; else return 0;}\n'%(self.MAXI0_BASE,self.MAXI0_RANGE)
184

185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
        for d in ld:
            fd=self.expand_define_maxi0(d, mode = "func_def",frmt_spcs = None)
            if fd:
                txt += fd + "\n"
        self.make_generated(os.path.abspath(os.path.join(os.path.dirname(__file__), directory)))
        with open(os.path.abspath(os.path.join(os.path.dirname(__file__), directory, filename)),"w") as out_file:
            print(header,file=out_file)
            print(txt,file=out_file)
        print ("%s are written to  to %s"%(description, os.path.abspath(os.path.join(os.path.dirname(__file__), directory, filename))))

    def save_defines_file(self, directory, filename):
        description = 'Constants and hardware addresses definitions to access x393 hardware registers'
        header = self.generated_fileHeader(filename,description)
        ld= self.define_macros()
        ld+=self.define_other_macros()
        txt = ""
        for d in ld:
            fd=self.expand_define_maxi0(d, mode = "defines",frmt_spcs = None)
            if fd:
                txt += fd + "\n"
        self.make_generated(os.path.abspath(os.path.join(os.path.dirname(__file__), directory)))
        with open(os.path.abspath(os.path.join(os.path.dirname(__file__), directory, filename)),"w") as out_file:
            print(header,file=out_file)
208
            print(self.gen_ifdef(filename),file=out_file)
209
            print(txt,file=out_file)
210 211
            print("#endif",file=out_file)
            
212 213 214 215 216 217 218
        print ("%s are written to  to %s"%(description, os.path.abspath(os.path.join(os.path.dirname(__file__), directory, filename))))
 
    def save_harware_map_file(self, directory, filename):
        description = 'Sorted hardware addresses map'
        header = self.generated_fileHeader(filename,description)
        ld= self.define_macros()
        ld+=self.define_other_macros()
219
        sam = self.expand_define_parameters(ld)
220
        txt = ""
221
        for d in sam:
222 223 224 225 226 227 228
#            print(self.expand_define_maxi0(d, mode = "defines", frmt_spcs = None))
            fd=self.expand_define_maxi0(d, mode = "defines",frmt_spcs = None)
            if fd:
                txt += fd + "\n"
        self.make_generated(os.path.abspath(os.path.join(os.path.dirname(__file__), directory)))
        with open(os.path.abspath(os.path.join(os.path.dirname(__file__), directory, filename)),"w") as out_file:
            print(header,file=out_file)
229
            print(self.gen_ifdef(filename),file=out_file)
230
            print(txt,file=out_file)
231 232
            print("#endif",file=out_file)
            
233 234 235
        print ("%s is written to  to %s"%(description, os.path.abspath(os.path.join(os.path.dirname(__file__), directory, filename))))
 
    def get_typedefs(self, frmt_spcs = None):
236
#        print("Will list bitfields typedef and comments")
237 238
        self.typedefs={}
        self.typedefs['u32']= {'comment':'unsigned 32-bit', 'code':'', 'size':32, 'type':''}
239 240 241 242
        stypedefs = ""
        
        stypedefs += self.get_typedef32(comment =   "Status generation control ",
                                 data =      self._enc_status_control(),
243
                                 name =      "x393_status_ctrl",  typ="rw",
244 245 246
                                 frmt_spcs = frmt_spcs)
        stypedefs += self.get_typedef32(comment =   "Memory channel operation mode",
                                 data =      self._enc_func_encode_mode_scan_tiled(),
247
                                 name =      "x393_mcntrl_mode_scan",  typ="wo",
248 249 250
                                 frmt_spcs = frmt_spcs)
        stypedefs += self.get_typedef32(comment =   "Memory channel window tile size/step (tiled only)",
                                 data =      self._enc_window_tile_whs(),
251
                                 name =      "x393_mcntrl_window_tile_whs",  typ="wo",
252 253 254
                                 frmt_spcs = frmt_spcs)
        stypedefs += self.get_typedef32(comment =   "Memory channel window size",
                                 data =      self._enc_window_wh(),
255
                                 name =      "x393_mcntrl_window_width_height",  typ="wo",
256 257 258
                                 frmt_spcs = frmt_spcs)
        stypedefs += self.get_typedef32(comment =   "Memory channel window position",
                                 data =      self._enc_window_lt(),
259
                                 name =      "x393_mcntrl_window_left_top",  typ="wo",
260 261 262
                                 frmt_spcs = frmt_spcs)
        stypedefs += self.get_typedef32(comment =   "Memory channel scan start (debug feature)",
                                 data =      self._enc_window_sxy(),
263
                                 name =      "x393_mcntrl_window_startx_starty",  typ="wo",
264 265 266
                                 frmt_spcs = frmt_spcs)
        stypedefs += self.get_typedef32(comment =   "Memory channel window full (padded) width",
                                 data =      self._enc_window_fw(),
267
                                 name =      "x393_mcntrl_window_full_width",  typ="wo",
268 269 270
                                 frmt_spcs = frmt_spcs)
        stypedefs += self.get_typedef32(comment =   "Memory channel last frame number in a buffer (number of frames minus 1)",
                                 data =      self._enc_window_last_frame_number(),
271
                                 name =      "x393_mcntrl_window_last_frame_num",  typ="wo",
272 273 274
                                 frmt_spcs = frmt_spcs)
        stypedefs += self.get_typedef32(comment =   "Memory channel frame start address increment (for next frame in a buffer)",
                                 data =      self._enc_window_frame_sa_inc(),
275
                                 name =      "x393_mcntrl_window_frame_sa_inc",  typ="wo",
276 277 278
                                 frmt_spcs = frmt_spcs)
        stypedefs += self.get_typedef32(comment =   "Memory channel frame start address for the first frame in a buffer",
                                 data =      self._enc_window_frame_sa(),
279
                                 name =      "x393_mcntrl_window_frame_sa",  typ="wo",
280
                                 frmt_spcs = frmt_spcs)
281 282 283 284 285
        stypedefs += self.get_typedef32(comment =   "Delay start of the channel from sensor frame sync (to allow frame sequencer issue commands)",
                                 data =      self._enc_frame_start_dly(),
                                 name =      "x393_mcntrl_frame_start_dly",  typ="wo",
                                 frmt_spcs = frmt_spcs)
        
286 287
        stypedefs += self.get_typedef32(comment =   "PS PIO (software-programmed DDR3) access sequences enable and reset",
                                 data =      self._enc_ps_pio_en_rst(),
288
                                 name =      "x393_ps_pio_en_rst",  typ="wo",
289 290 291
                                 frmt_spcs = frmt_spcs)
        stypedefs += self.get_typedef32(comment =   "PS PIO (software-programmed DDR3) access sequences control",
                                 data =      self._enc_ps_pio_cmd(),
292
                                 name =      "x393_ps_pio_cmd",  typ="wo",
293 294 295 296
                                 frmt_spcs = frmt_spcs)

        stypedefs += self.get_typedef32(comment =   "x393 generic status register",
                                 data =      self._enc_status(),
297
                                 name =      "x393_status",  typ="ro",
298 299 300
                                 frmt_spcs = frmt_spcs)
        stypedefs += self.get_typedef32(comment =   "Memory PHY status",
                                 data =      self._enc_status_mcntrl_phy(),
301
                                 name =      "x393_status_mcntrl_phy",  typ="ro",
302 303 304
                                 frmt_spcs = frmt_spcs)
        stypedefs += self.get_typedef32(comment =   "Memory controller requests status",
                                 data =      self._enc_status_mcntrl_top(),
305
                                 name =      "x393_status_mcntrl_top",  typ="ro",
306 307 308
                                 frmt_spcs = frmt_spcs)
        stypedefs += self.get_typedef32(comment =   "Memory software access status",
                                 data =      self._enc_status_mcntrl_ps(),
309
                                 name =      "x393_status_mcntrl_ps",  typ="ro",
310 311 312
                                 frmt_spcs = frmt_spcs)
        stypedefs += self.get_typedef32(comment =   "Memory test channels access status",
                                 data =      self._enc_status_lintile(),
313
                                 name =      "x393_status_mcntrl_lintile",  typ="ro",
314 315 316
                                 frmt_spcs = frmt_spcs)
        stypedefs += self.get_typedef32(comment =   "Memory test channels status",
                                 data =      self._enc_status_testchn(),
317
                                 name =      "x393_status_mcntrl_testchn",  typ="ro",
318 319 320
                                 frmt_spcs = frmt_spcs)
        stypedefs += self.get_typedef32(comment =   "Membridge channel status",
                                 data =      self._enc_status_membridge(),
321
                                 name =      "x393_status_membridge",  typ="ro",
322 323 324
                                 frmt_spcs = frmt_spcs)
        
        stypedefs += self.get_typedef32(comment =   "Sensor/multiplexer I/O pins status",
325 326 327
                                 data =      [self._enc_status_sens_io(),
                                              self._enc_status_sens_io_hispi(),
                                              self._enc_status_sens_io_vospi()],
328
                                 name =      "x393_status_sens_io",  typ="ro",
329 330 331 332
                                 frmt_spcs = frmt_spcs)

        stypedefs += self.get_typedef32(comment =   "Sensor/multiplexer i2c status",
                                 data =      self._enc_status_sens_i2c(),
333
                                 name =      "x393_status_sens_i2c",  typ="ro",
334 335
                                 frmt_spcs = frmt_spcs)

336 337 338 339 340
        stypedefs += self.get_typedef32(comment =   "Sensor measured timing between sof/eof/sol/eol",
                                 data =      self._enc_status_sensor_timing(),
                                 name =      "x393_status_sensor_timing",  typ="ro",
                                 frmt_spcs = frmt_spcs)

341 342
        stypedefs += self.get_typedef32(comment =   "Command bits for test01 module (test frame memory accesses)",
                                 data =      self._enc_test01_mode(),
343
                                 name =      "x393_test01_mode",  typ="wo",
344 345 346 347
                                 frmt_spcs = frmt_spcs)

        stypedefs += self.get_typedef32(comment =   "Command for membridge",
                                 data =      self._enc_membridge_cmd(),
348
                                 name =      "x393_membridge_cmd",  typ="wo",
349
                                 frmt_spcs = frmt_spcs)
350
        """
351 352
        stypedefs += self.get_typedef32(comment =   "Cache mode for membridge",
                                 data =      self._enc_membridge_mode(),
353
                                 name =      "x393_membridge_mode",  typ="wo",
354
                                 frmt_spcs = frmt_spcs)
355 356 357 358 359
        """                                 
        stypedefs += self.get_typedef32(comment =   "Interrupt handling commands for Membridge module",
                                 data =      self._enc_membridge_ctrl_irq(),
                                 name =      "x393_membridge_ctrl_irq",  typ="wo",
                                 frmt_spcs = frmt_spcs)
360 361
        stypedefs += self.get_typedef32(comment =   "Address in 64-bit words",
                                 data =      self._enc_u29(),
362
                                 name =      "u29",  typ="wo",
363 364 365 366 367 368 369
                                 frmt_spcs = frmt_spcs)
        
        stypedefs += self.get_typedef32(comment =   "I2C contol/table data",
                                 data =      [self._enc_i2c_tbl_addr(), # generate typedef union
                                              self._enc_i2c_tbl_wmode(),
                                              self._enc_i2c_tbl_rmode(),
                                              self._enc_i2c_ctrl()],
370
                                 name =      "x393_i2c_ctltbl",  typ="wo",
371 372 373 374
                                 frmt_spcs = frmt_spcs)
        
        stypedefs += self.get_typedef32(comment =   "Write sensor channel mode register",
                                 data =      self._enc_sens_mode(),
375
                                 name =      "x393_sens_mode",  typ="wo",
376 377 378 379
                                 frmt_spcs = frmt_spcs)

        stypedefs += self.get_typedef32(comment =   "Write number of sensor frames to combine into one virtual (linescan mode)",
                                 data =      self._enc_sens_sync_mult(),
380
                                 name =      "x393_sens_sync_mult",  typ="wo",
381 382 383 384
                                 frmt_spcs = frmt_spcs)

        stypedefs += self.get_typedef32(comment =   "Write sensor number of lines to delay frame sync",
                                 data =      self._enc_sens_sync_late(),
385
                                 name =      "x393_sens_sync_late",  typ="wo",
386 387 388 389
                                 frmt_spcs = frmt_spcs)

        stypedefs += self.get_typedef32(comment =   "Configure memory controller priorities",
                                 data =      self._enc_mcntrl_priorities(),
Andrey Filippov's avatar
Andrey Filippov committed
390
                                 name =      "x393_arbiter_pri",  typ="rw",
391 392 393 394
                                 frmt_spcs = frmt_spcs)

        stypedefs += self.get_typedef32(comment =   "Enable/disable memory controller channels",
                                 data =      self._enc_mcntrl_chnen(),
395
                                 name =      "x393_mcntr_chn_en",  typ="rw",
396 397 398 399
                                 frmt_spcs = frmt_spcs)
        
        stypedefs += self.get_typedef32(comment =   "DQS and DQM patterns (DQM - 0, DQS 0xaa or 0x55)",
                                 data =      self._enc_mcntrl_dqs_dqm_patterns(),
400
                                 name =      "x393_mcntr_dqs_dqm_patt",  typ="rw",
401 402 403
                                 frmt_spcs = frmt_spcs)
        stypedefs += self.get_typedef32(comment =   "DQ and DQS tristate control when turning on and off",
                                 data =      self._enc_mcntrl_dqs_dq_tri(),
404
                                 name =      "x393_mcntr_dqs_dqm_tri",  typ="rw",
405
                                 frmt_spcs = frmt_spcs)
406 407 408
        
        stypedefs += self.get_typedef32(comment =   "DDR3 memory controller I/O delay",
                                 data =      self._enc_mcntrl_dly(),
409
                                 name =      "x393_dly",  typ="rw",
410 411 412
                                 frmt_spcs = frmt_spcs)
        stypedefs += self.get_typedef32(comment =   "Extra delay in mclk (fDDR/2) cycles) to data write buffer",
                                 data =      self._enc_wbuf_dly(),
413
                                 name =      "x393_wbuf_dly",  typ="rw",
414 415 416 417
                                 frmt_spcs = frmt_spcs)
        
        stypedefs += self.get_typedef32(comment =   "Control for the gamma-conversion module",
                                 data =      self._enc_gamma_ctl(),
418
                                 name =      "x393_gamma_ctl",  typ="rw",
419 420 421 422
                                 frmt_spcs = frmt_spcs)
        stypedefs += self.get_typedef32(comment =   "Write gamma table address/data",
                                 data =      [self._enc_gamma_tbl_addr(), # generate typedef union
                                              self._enc_gamma_tbl_data()],
423
                                 name =      "x393_gamma_tbl",  typ="wo",
424 425 426
                                 frmt_spcs = frmt_spcs)
        stypedefs += self.get_typedef32(comment =   "Heights of the first two subchannels frames",
                                 data =      self._enc_gamma_height01(),
427
                                 name =      "x393_gamma_height01m1",  typ="rw",
428 429 430
                                 frmt_spcs = frmt_spcs)
        stypedefs += self.get_typedef32(comment =   "Height of the third subchannel frame",
                                 data =      self._enc_gamma_height2(),
431
                                 name =      "x393_gamma_height2m1",  typ="rw",
432 433 434 435
                                 frmt_spcs = frmt_spcs)
        
        stypedefs += self.get_typedef32(comment =   "Sensor port I/O control",
                                 data =      [self._enc_sensio_ctrl_par12(),
436 437
                                              self._enc_sensio_ctrl_hispi(),
                                              self._enc_sensio_ctrl_vospi()],
438
                                 name =      "x393_sensio_ctl",  typ="wo",
439 440 441
                                 frmt_spcs = frmt_spcs)
        stypedefs += self.get_typedef32(comment =   "Programming interface for multiplexer FPGA",
                                 data =      self._enc_sensio_jtag(),
442
                                 name =      "x393_sensio_jtag",  typ="wo",
443
                                 frmt_spcs = frmt_spcs)
444
        """
445 446 447
        stypedefs += self.get_typedef32(comment =   "Sensor delays (uses 4 DWORDs)",
                                 data =      [self._enc_sensio_dly_par12(),
                                              self._enc_sensio_dly_hispi()],
448
                                 name =      "x393_sensio_dly",  typ="rw",
449
                                 frmt_spcs = frmt_spcs)
450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471
        """                                 
        stypedefs += self.get_typedef32(comment =   "Sensor i/o timing register 0 (different meanings for different sensor types)",
                                 data =      [self._enc_sensio_par12_tim0(),
                                              self._enc_sensio_hispi_tim0()],
                                 name =      "x393_sensio_tim0",  typ="rw",
                                 frmt_spcs = frmt_spcs)
        stypedefs += self.get_typedef32(comment =   "Sensor i/o timing register 1 (different meanings for different sensor types)",
                                 data =      [self._enc_sensio_par12_tim1(),
                                              self._enc_sensio_hispi_tim1()],
                                 name =      "x393_sensio_tim1",  typ="rw",
                                 frmt_spcs = frmt_spcs)
        stypedefs += self.get_typedef32(comment =   "Sensor i/o timing register 2 (different meanings for different sensor types)",
                                 data =      [self._enc_sensio_par12_tim2(),
                                              self._enc_sensio_hispi_tim2()],
                                 name =      "x393_sensio_tim2",  typ="rw",
                                 frmt_spcs = frmt_spcs)
        stypedefs += self.get_typedef32(comment =   "Sensor i/o timing register 3 (different meanings for different sensor types)",
                                 data =      [self._enc_sensio_par12_tim3(),
                                              self._enc_sensio_hispi_tim3()],
                                 name =      "x393_sensio_tim3",  typ="rw",
                                 frmt_spcs = frmt_spcs)

472 473
        stypedefs += self.get_typedef32(comment =   "Set sensor frame width (0 - use received)",
                                 data =      self._enc_sensio_width(),
474
                                 name =      "x393_sensio_width",  typ="rw",
475 476 477 478 479 480 481 482 483 484 485 486 487
                                 frmt_spcs = frmt_spcs)

        stypedefs += self.get_typedef32(comment =   "Lens vignetting parameter (write address first, then data that may overlap som address bits)",
                                 data =      [self._enc_lens_addr(),
                                              self._enc_lens_ax(),
                                              self._enc_lens_ay(),
                                              self._enc_lens_bx(),
                                              self._enc_lens_by(),
                                              self._enc_lens_c(),
                                              self._enc_lens_scale(),
                                              self._enc_lens_fatzero_in(),
                                              self._enc_lens_fatzero_out(),
                                              self._enc_lens_post_scale()],
488
                                 name =      "x393_lens_corr",  typ="wo",
489 490 491
                                 frmt_spcs = frmt_spcs)
        stypedefs += self.get_typedef32(comment =   "Height of the subchannel frame for vignetting correction",
                                 data =      self._enc_lens_height_m1(),
492
                                 name =      "x393_lens_height_m1",  typ="rw",
493 494 495 496
                                 frmt_spcs = frmt_spcs)

        stypedefs += self.get_typedef32(comment =   "Histogram window left/top margins",
                                 data =      self._enc_histogram_lt(),
497
                                 name =      "x393_hist_left_top",  typ="rw",
498 499 500
                                 frmt_spcs = frmt_spcs)
        stypedefs += self.get_typedef32(comment =   "Histogram window width and height minus 1 (0 use full)",
                                 data =      self._enc_histogram_wh_m1(),
501
                                 name =      "x393_hist_width_height_m1",  typ="rw",
502 503 504
                                 frmt_spcs = frmt_spcs)
        stypedefs += self.get_typedef32(comment =   "Histograms DMA mode",
                                 data =      self._enc_hist_saxi_mode(),
505
                                 name =      "x393_hist_saxi_mode",  typ="rw",
506 507 508
                                 frmt_spcs = frmt_spcs)
        stypedefs += self.get_typedef32(comment =   "Histograms DMA addresses",
                                 data =      self._enc_hist_saxi_page_addr(),
509 510 511 512
                                 name =      "x393_hist_saxi_addr",  typ="rw",
                                 frmt_spcs = frmt_spcs)
        stypedefs += self.get_typedef32(comment =   "Compressor mode control",
                                 data =      self._enc_cmprs_mode(),
513
                                 name =      "x393_cmprs_mode",  typ="rw", # to read back last written
514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533
                                 frmt_spcs = frmt_spcs)
        stypedefs += self.get_typedef32(comment =   "Compressor coring mode (table number)",
                                 data =      self._enc_cmprs_coring_sel(),
                                 name =      "x393_cmprs_coring_mode",  typ="rw",
                                 frmt_spcs = frmt_spcs)
        stypedefs += self.get_typedef32(comment =   "Compressor color saturation",
                                 data =      self._enc_cmprs_color_sat(),
                                 name =      "x393_cmprs_colorsat",  typ="rw",
                                 frmt_spcs = frmt_spcs)
        stypedefs += self.get_typedef32(comment =   "Compressor frame format",
                                 data =      self._enc_cmprs_format(),
                                 name =      "x393_cmprs_frame_format",  typ="rw",
                                 frmt_spcs = frmt_spcs)
        stypedefs += self.get_typedef32(comment =   "Compressor interrupts control",
                                 data =      self._enc_cmprs_interrupts(),
                                 name =      "x393_cmprs_interrupts",  typ="wo",
                                 frmt_spcs = frmt_spcs)
        stypedefs += self.get_typedef32(comment =   "Compressor tables load control",
                                 data =      self._enc_cmprs_table_addr(),
                                 name =      "x393_cmprs_table_addr",  typ="wo",
534
                                 frmt_spcs = frmt_spcs)
535 536 537 538
        stypedefs += self.get_typedef32(comment =   "Compressor channel status",
                                 data =      self._enc_cmprs_status(),
                                 name =      "x393_cmprs_status",  typ="ro",
                                 frmt_spcs = frmt_spcs)
539

540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596
        stypedefs += self.get_typedef32(comment =   "Compressor DMA buffer address (in 32-byte blocks)",
                                 data =      self._enc_cmprs_afimux_sa(),
                                 name =      "x393_afimux_sa",  typ="rw",
                                 frmt_spcs = frmt_spcs)
        stypedefs += self.get_typedef32(comment =   "Compressor DMA buffer length (in 32-byte blocks)",
                                 data =      self._enc_cmprs_afimux_len(),
                                 name =      "x393_afimux_len", typ="rw",
                                 frmt_spcs = frmt_spcs)
        stypedefs += self.get_typedef32(comment =   "Compressor DMA channels reset",
                                 data =      self._enc_cmprs_afimux_rst(),
                                 name =      "x393_afimux_rst", typ="rw",
                                 frmt_spcs = frmt_spcs)
        stypedefs += self.get_typedef32(comment =   "Compressor DMA enable (global and channels)",
                                 data =      self._enc_cmprs_afimux_en(),
                                 name =      "x393_afimux_en", typ="wo",
                                 frmt_spcs = frmt_spcs)
        stypedefs += self.get_typedef32(comment =   "Compressor DMA report mode",
                                 data =      self._enc_cmprs_afimux_report(),
                                 name =      "x393_afimux_report", typ="wo",
                                 frmt_spcs = frmt_spcs)
        stypedefs += self.get_typedef32(comment =   "Compressor DMA status",
                                 data =      self._enc_cmprs_afimux_status(),
                                 name =      "x393_afimux_status", typ="ro",
                                 frmt_spcs = frmt_spcs)
        stypedefs += self.get_typedef32(comment =   "GPIO output control",
                                 data =      self._enc_cmprs_gpio_out(),
                                 name =      "x393_gpio_set_pins", typ="wo",
                                 frmt_spcs = frmt_spcs)
        stypedefs += self.get_typedef32(comment =   "GPIO pins status",
                                 data =      self._enc_cmprs_gpio_status(),
                                 name =      "x393_gpio_status", typ="ro",
                                 frmt_spcs = frmt_spcs)
        stypedefs += self.get_typedef32(comment =   "RTC seconds",
                                 data =      self._enc_rtc_sec(),
                                 name =      "x393_rtc_sec", typ="rw",
                                 frmt_spcs = frmt_spcs)
        stypedefs += self.get_typedef32(comment =   "RTC microseconds",
                                 data =      self._enc_rtc_usec(),
                                 name =      "x393_rtc_usec", typ="rw",
                                 frmt_spcs = frmt_spcs)
        stypedefs += self.get_typedef32(comment =   "RTC correction",
                                 data =      self._enc_rtc_corr(),
                                 name =      "x393_rtc_corr", typ="rw",
                                 frmt_spcs = frmt_spcs)
        stypedefs += self.get_typedef32(comment =   "RTC status",
                                 data =      self._enc_rtc_status(),
                                 name =      "x393_rtc_status", typ="ro",
                                 frmt_spcs = frmt_spcs)

        stypedefs += self.get_typedef32(comment =   "CAMSYNC I/O configuration",
                                 data =      self._enc_camsync_lines(),
                                 name =      "x393_camsync_io", typ="wo",
                                 frmt_spcs = frmt_spcs)
        stypedefs += self.get_typedef32(comment =   "CAMSYNC mode",
                                 data =      self._enc_camsync_mode(),
                                 name =      "x393_camsync_mode", typ="wo",
                                 frmt_spcs = frmt_spcs)
597 598 599 600
        stypedefs += self.get_typedef32(comment =   "CMDFRAMESEQ mode",
                                 data =      self._enc_cmdframeseq_mode(),
                                 name =      "x393_cmdframeseq_mode", typ="wo",
                                 frmt_spcs = frmt_spcs)
601 602 603 604
        stypedefs += self.get_typedef32(comment =   "CMDFRAMESEQ mode",
                                 data =      self._enc_cmdseqmux_status(),
                                 name =      "x393_cmdseqmux_status", typ="ro",
                                 frmt_spcs = frmt_spcs)
605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621
        stypedefs += self.get_typedef32(comment =   "Event logger status",
                                 data =      self._enc_logger_status(),
                                 name =      "x393_logger_status", typ="ro",
                                 frmt_spcs = frmt_spcs)
        stypedefs += self.get_typedef32(comment =   "Event logger register address",
                                 data =      self._enc_logger_reg_addr(),
                                 name =      "x393_logger_address", typ="wo",
                                 frmt_spcs = frmt_spcs)
        stypedefs += self.get_typedef32(comment =   "Event logger register data",
                                 data =      [self._enc_logger_conf(),
                                              self._enc_logger_data()],
                                 name =      "x393_logger_data", typ="wo",
                                 frmt_spcs = frmt_spcs)
        stypedefs += self.get_typedef32(comment =   "MULT_SAXI DMA addresses/lengths in 32-bit DWORDS",
                                 data =      self._enc_mult_saxi_addr(),
                                 name =      "x393_mult_saxi_al", typ="rw", # some - wo, others - ro
                                 frmt_spcs = frmt_spcs)
622 623 624 625 626 627 628 629 630 631 632 633
        stypedefs += self.get_typedef32(comment =   "MULT_SAXI DMA DW address bit to change for interrupt to be generated",
                                 data =      self._enc_mult_saxi_irqlen(),
                                 name =      "x393_mult_saxi_irqlen", typ="rw", # some - wo, others - ro
                                 frmt_spcs = frmt_spcs)
        stypedefs += self.get_typedef32(comment =   "MULT_SAXI DMA mode register (per channel enable/run)",
                                 data =      self._enc_mult_saxi_mode(),
                                 name =      "x393_mult_saxi_mode", typ="rw", # some - wo, others - ro
                                 frmt_spcs = frmt_spcs)
        stypedefs += self.get_typedef32(comment =   "MULT_SAXI per-channel interrupt control",
                                 data =      self._enc_mult_saxi_interrupts(),
                                 name =      "x393_mult_saxi_interrupts", typ="wo", # some - wo, others - ro
                                 frmt_spcs = frmt_spcs)
634 635 636 637
        stypedefs += self.get_typedef32(comment =   "MULT_SAXI interrupt status",
                                 data =      self._enc_mult_saxi_status(),
                                 name =      "x393_mult_saxi_status", typ="ro",
                                 frmt_spcs = frmt_spcs)
638 639 640 641 642 643 644 645 646 647 648 649 650 651 652

        stypedefs += self.get_typedef32(comment =   "MULTICLK reset/power down controls",
                                 data =      self._enc_multiclk_ctl(),
                                 name =      "x393_multiclk_ctl", typ="rw",
                                 frmt_spcs = frmt_spcs)
        stypedefs += self.get_typedef32(comment =   "MULTICLK status",
                                 data =      self._enc_multiclk_status(),
                                 name =      "x393_multiclk_status", typ="ro",
                                 frmt_spcs = frmt_spcs)

        stypedefs += self.get_typedef32(comment =   "DEBUG status",
                                 data =      self._enc_debug_status(),
                                 name =      "x393_debug_status", typ="ro",
                                 frmt_spcs = frmt_spcs)
        
653 654 655 656 657 658
        return stypedefs
    
    def define_macros(self):
        #memory arbiter priorities
        ba = vrlg.CONTROL_ADDR
        z3= (0,3)
659
        z7 = (0,7)
660
        z14= (0,14)
661
        z15= (0,15)
662
        z31= (0,31)
663 664 665 666 667
        ia = 1
        c = "chn"
        sdefines = []
        sdefines +=[
            (('R/W addresses to set up memory arbiter priorities. For sensors  (chn = 8..11), for compressors - 12..15',)),
Andrey Filippov's avatar
Andrey Filippov committed
668
            (("X393_MCNTRL_ARBITER_PRIORITY",              c, vrlg.MCONTR_ARBIT_ADDR +             ba, ia, z15, "x393_arbiter_pri", "rw",                "Set memory arbiter priority (currently r/w, may become just wo)"))]        
669 670 671

        sdefines +=[
            (('Enable/disable memory channels (bits in a 16-bit word). For sensors  (chn = 8..11), for compressors - 12..15',)),
672 673 674
            (("X393_MCNTRL_CHN_EN",     c, vrlg.MCONTR_TOP_16BIT_ADDR +  vrlg.MCONTR_TOP_16BIT_CHN_EN +    ba,     0, None, "x393_mcntr_chn_en", "rw",   "Enable/disable memory channels (currently r/w, may become just wo)")),
            (("X393_MCNTRL_DQS_DQM_PATT",c, vrlg.MCONTR_PHY_16BIT_ADDR+  vrlg.MCONTR_PHY_16BIT_PATTERNS +  ba,     0, None, "x393_mcntr_dqs_dqm_patt", "rw",     "Setup DQS and DQM patterns")),
            (("X393_MCNTRL_DQ_DQS_TRI", c, vrlg.MCONTR_PHY_16BIT_ADDR +  vrlg.MCONTR_PHY_16BIT_PATTERNS_TRI+ ba,   0, None, "x393_mcntr_dqs_dqm_tri", "rw",      "Setup DQS and DQ on/off sequence")),
675
            (("Following enable/disable addresses can be written with any data, only addresses matter",)),
676 677 678 679 680 681 682 683 684 685
            (("X393_MCNTRL_DIS",        c, vrlg.MCONTR_TOP_0BIT_ADDR +   vrlg.MCONTR_TOP_0BIT_MCONTR_EN +  ba + 0, 0, None, "","",                       "Disable DDR3 memory controller")),        
            (("X393_MCNTRL_EN",         c, vrlg.MCONTR_TOP_0BIT_ADDR +   vrlg.MCONTR_TOP_0BIT_MCONTR_EN +  ba + 1, 0, None, "","",                       "Enable DDR3 memory controller")),        
            (("X393_MCNTRL_REFRESH_DIS",c, vrlg.MCONTR_TOP_0BIT_ADDR +   vrlg.MCONTR_TOP_0BIT_REFRESH_EN + ba + 0, 0, None, "","",                       "Disable DDR3 memory refresh")),        
            (("X393_MCNTRL_REFRESH_EN", c, vrlg.MCONTR_TOP_0BIT_ADDR +   vrlg.MCONTR_TOP_0BIT_REFRESH_EN + ba + 1, 0, None, "","",                       "Enable DDR3 memory refresh")),        
            (("X393_MCNTRL_SDRST_DIS",  c, vrlg.MCONTR_PHY_0BIT_ADDR +   vrlg.MCONTR_PHY_0BIT_SDRST_ACT +  ba + 0, 0, None, "","",                       "Disable DDR3 memory reset")),        
            (("X393_MCNTRL_SDRST_EN",   c, vrlg.MCONTR_PHY_0BIT_ADDR +   vrlg.MCONTR_PHY_0BIT_SDRST_ACT +  ba + 1, 0, None, "","",                       "Enable DDR3 memory reset")),        
            (("X393_MCNTRL_CKE_DIS",    c, vrlg.MCONTR_PHY_0BIT_ADDR +   vrlg.MCONTR_PHY_0BIT_CKE_EN +     ba + 0, 0, None, "","",                       "Disable DDR3 memory CKE")),        
            (("X393_MCNTRL_CKE_EN",     c, vrlg.MCONTR_PHY_0BIT_ADDR +   vrlg.MCONTR_PHY_0BIT_CKE_EN +     ba + 1, 0, None, "","",                       "Enable DDR3 memory CKE")),        
            (("X393_MCNTRL_CMDA_DIS",   c, vrlg.MCONTR_PHY_0BIT_ADDR +   vrlg.MCONTR_PHY_0BIT_CMDA_EN +    ba + 0, 0, None, "","",                       "Disable DDR3 memory command/address lines")),        
            (("X393_MCNTRL_CMDA_EN",    c, vrlg.MCONTR_PHY_0BIT_ADDR +   vrlg.MCONTR_PHY_0BIT_CMDA_EN +    ba + 1, 0, None, "","",                       "Enable DDR3 memory command/address lines")),        
686 687 688 689 690
            ]        
        ba = vrlg.CONTROL_ADDR
        #"x393_dly_rw"
        sdefines +=[
            (('Set DDR3 memory controller I/O delays and other timing parameters (should use individually calibrated values)',)),
691 692 693 694 695 696 697 698 699 700 701
            (("X393_MCNTRL_DQ_ODLY0",   c, vrlg.LD_DLY_LANE0_ODELAY +    ba,     1, z7,   "x393_dly", "rw",    "Lane0 DQ output delays ")),
            (("X393_MCNTRL_DQ_ODLY1",   c, vrlg.LD_DLY_LANE1_ODELAY +    ba,     1, z7,   "x393_dly", "rw",    "Lane1 DQ output delays ")),
            (("X393_MCNTRL_DQ_IDLY0",   c, vrlg.LD_DLY_LANE0_IDELAY +    ba,     1, z7,   "x393_dly", "rw",    "Lane0 DQ input delays ")),
            (("X393_MCNTRL_DQ_IDLY1",   c, vrlg.LD_DLY_LANE1_IDELAY +    ba,     1, z7,   "x393_dly", "rw",    "Lane1 DQ input delays ")),
            (("X393_MCNTRL_DQS_ODLY0",  c, vrlg.LD_DLY_LANE0_ODELAY +    ba + 8, 0, None, "x393_dly", "rw",    "Lane0 DQS output delay ")),
            (("X393_MCNTRL_DQS_ODLY1",  c, vrlg.LD_DLY_LANE1_ODELAY +    ba + 8, 0, None, "x393_dly", "rw",    "Lane1 DQS output delay ")),
            (("X393_MCNTRL_DQS_IDLY0",  c, vrlg.LD_DLY_LANE0_IDELAY +    ba + 8, 0, None, "x393_dly", "rw",    "Lane0 DQS input delay ")),
            (("X393_MCNTRL_DQS_IDLY1",  c, vrlg.LD_DLY_LANE1_IDELAY +    ba + 8, 0, None, "x393_dly", "rw",    "Lane1 DQS input delay ")),
            (("X393_MCNTRL_DM_ODLY0",   c, vrlg.LD_DLY_LANE0_ODELAY +    ba + 9, 0, None, "x393_dly", "rw",    "Lane0 DM output delay ")),
            (("X393_MCNTRL_DM_ODLY1",   c, vrlg.LD_DLY_LANE1_ODELAY +    ba + 9, 0, None, "x393_dly", "rw",    "Lane1 DM output delay ")),
            (("X393_MCNTRL_CMDA_ODLY",  c, vrlg.LD_DLY_CMDA +            ba,     1, z31,  "x393_dly", "rw",    "Address, bank and commands delays")),
Andrey Filippov's avatar
Andrey Filippov committed
702
            (("X393_MCNTRL_PHASE",      c, vrlg.LD_DLY_PHASE +           ba,     0, None, "x393_dly", "rw",    "Clock phase")),
703 704
            (("X393_MCNTRL_DLY_SET",    c, vrlg.MCONTR_PHY_0BIT_ADDR +   vrlg.MCONTR_PHY_0BIT_DLY_SET +      ba, 0, None, "", "",             "Set all pre-programmed delays")),
            (("X393_MCNTRL_WBUF_DLY",   c, vrlg.MCONTR_PHY_16BIT_ADDR +  vrlg.MCONTR_PHY_16BIT_WBUF_DELAY +  ba, 0, None, "x393_wbuf_dly", "rw", "Set write buffer delay")),
705 706 707 708 709 710
            ]        
        ba = vrlg.MCONTR_SENS_BASE
        ia = vrlg.MCONTR_SENS_INC
        c = "chn"
        sdefines +=[
            (('Write-only addresses to program memory channels for sensors  (chn = 0..3), memory channels 8..11',)),
711
            (("X393_SENS_MCNTRL_SCANLINE_MODE",            c, vrlg.MCNTRL_SCANLINE_MODE +             ba, ia, z3, "x393_mcntrl_mode_scan", "wo",             "Set mode register (write last after other channel registers are set)")),
712
            (("X393_SENS_MCNTRL_SCANLINE_STATUS_CNTRL",    c, vrlg.MCNTRL_SCANLINE_STATUS_CNTRL +     ba, ia, z3, "x393_status_ctrl", "rw",                  "Set status control register (status update mode)")),
713 714 715 716 717 718
            (("X393_SENS_MCNTRL_SCANLINE_STARTADDR",       c, vrlg.MCNTRL_SCANLINE_STARTADDR +        ba, ia, z3, "x393_mcntrl_window_frame_sa", "wo",       "Set frame start address")),
            (("X393_SENS_MCNTRL_SCANLINE_FRAME_SIZE",      c, vrlg.MCNTRL_SCANLINE_FRAME_SIZE +       ba, ia, z3, "x393_mcntrl_window_frame_sa_inc", "wo",   "Set frame size (address increment)")),
            (("X393_SENS_MCNTRL_SCANLINE_FRAME_LAST",      c, vrlg.MCNTRL_SCANLINE_FRAME_LAST +       ba, ia, z3, "x393_mcntrl_window_last_frame_num", "wo", "Set last frame number (number of frames in buffer minus 1)")),
            (("X393_SENS_MCNTRL_SCANLINE_FRAME_FULL_WIDTH",c, vrlg.MCNTRL_SCANLINE_FRAME_FULL_WIDTH + ba, ia, z3, "x393_mcntrl_window_full_width", "wo",     "Set frame full(padded) width")),
            (("X393_SENS_MCNTRL_SCANLINE_WINDOW_WH",       c, vrlg.MCNTRL_SCANLINE_WINDOW_WH +        ba, ia, z3, "x393_mcntrl_window_width_height", "wo",   "Set frame window size")),
            (("X393_SENS_MCNTRL_SCANLINE_WINDOW_X0Y0",     c, vrlg.MCNTRL_SCANLINE_WINDOW_X0Y0 +      ba, ia, z3, "x393_mcntrl_window_left_top", "wo",       "Set frame position")),
719 720
            (("X393_SENS_MCNTRL_SCANLINE_STARTXY",         c, vrlg.MCNTRL_SCANLINE_WINDOW_STARTXY +   ba, ia, z3, "x393_mcntrl_window_startx_starty", "wo",  "Set startXY register")),
            (("X393_SENS_MCNTRL_SCANLINE_START_DELAY",     c, vrlg.MCNTRL_SCANLINE_START_DELAY +      ba, ia, z3, "x393_mcntrl_frame_start_dly", "wo",       "Set dDelay start of the channel from sensor frame sync"))]
721 722 723 724
        ba = vrlg.MCONTR_CMPRS_BASE
        ia = vrlg.MCONTR_CMPRS_INC
        sdefines +=[
            (('Write-only addresses to program memory channels for compressors (chn = 0..3), memory channels 12..15',)),
725
            (("X393_SENS_MCNTRL_TILED_MODE",               c, vrlg.MCNTRL_TILED_MODE +                ba, ia, z3, "x393_mcntrl_mode_scan", "wo",             "Set mode register (write last after other channel registers are set)")),
726
            (("X393_SENS_MCNTRL_TILED_STATUS_CNTRL",       c, vrlg.MCNTRL_TILED_STATUS_CNTRL +        ba, ia, z3, "x393_status_ctrl", "rw",                  "Set status control register (status update mode)")),
727 728 729 730 731 732 733 734
            (("X393_SENS_MCNTRL_TILED_STARTADDR",          c, vrlg.MCNTRL_TILED_STARTADDR +           ba, ia, z3, "x393_mcntrl_window_frame_sa", "wo",       "Set frame start address")),
            (("X393_SENS_MCNTRL_TILED_FRAME_SIZE",         c, vrlg.MCNTRL_TILED_FRAME_SIZE +          ba, ia, z3, "x393_mcntrl_window_frame_sa_inc", "wo",   "Set frame size (address increment)")),
            (("X393_SENS_MCNTRL_TILED_FRAME_LAST",         c, vrlg.MCNTRL_TILED_FRAME_LAST +          ba, ia, z3, "x393_mcntrl_window_last_frame_num", "wo", "Set last frame number (number of frames in buffer minus 1)")),
            (("X393_SENS_MCNTRL_TILED_FRAME_FULL_WIDTH",   c, vrlg.MCNTRL_TILED_FRAME_FULL_WIDTH +    ba, ia, z3, "x393_mcntrl_window_full_width", "wo",     "Set frame full(padded) width")),
            (("X393_SENS_MCNTRL_TILED_WINDOW_WH",          c, vrlg.MCNTRL_TILED_WINDOW_WH +           ba, ia, z3, "x393_mcntrl_window_width_height", "wo",   "Set frame window size")),
            (("X393_SENS_MCNTRL_TILED_WINDOW_X0Y0",        c, vrlg.MCNTRL_TILED_WINDOW_X0Y0 +         ba, ia, z3, "x393_mcntrl_window_left_top", "wo",       "Set frame position")),
            (("X393_SENS_MCNTRL_TILED_STARTXY",            c, vrlg.MCNTRL_TILED_WINDOW_STARTXY +      ba, ia, z3, "x393_mcntrl_window_startx_starty", "wo",  "Set startXY register")),
            (("X393_SENS_MCNTRL_TILED_TILE_WHS",           c, vrlg.MCNTRL_TILED_TILE_WHS +            ba, ia, z3, "x393_mcntrl_window_tile_whs", "wo",       "Set tile size/step (tiled mode only)"))]
735 736 737 738 739 740

        ba = vrlg.MCNTRL_SCANLINE_CHN1_ADDR
        ia = 0
        c =  ""
        sdefines +=[
            (('Write-only addresses to program memory channel for membridge, memory channel 1',)),
741
            (("X393_MEMBRIDGE_SCANLINE_MODE",            c, vrlg.MCNTRL_SCANLINE_MODE +             ba, 0, None, "x393_mcntrl_mode_scan", "wo",             "Set mode register (write last after other channel registers are set)")),
742
            (("X393_MEMBRIDGE_SCANLINE_STATUS_CNTRL",    c, vrlg.MCNTRL_SCANLINE_STATUS_CNTRL +     ba, 0, None, "x393_status_ctrl", "rw",                  "Set status control register (status update mode)")),
743 744 745 746 747 748 749
            (("X393_MEMBRIDGE_SCANLINE_STARTADDR",       c, vrlg.MCNTRL_SCANLINE_STARTADDR +        ba, 0, None, "x393_mcntrl_window_frame_sa", "wo",       "Set frame start address")),
            (("X393_MEMBRIDGE_SCANLINE_FRAME_SIZE",      c, vrlg.MCNTRL_SCANLINE_FRAME_SIZE +       ba, 0, None, "x393_mcntrl_window_frame_sa_inc", "wo",   "Set frame size (address increment)")),
            (("X393_MEMBRIDGE_SCANLINE_FRAME_LAST",      c, vrlg.MCNTRL_SCANLINE_FRAME_LAST +       ba, 0, None, "x393_mcntrl_window_last_frame_num", "wo", "Set last frame number (number of frames in buffer minus 1)")),
            (("X393_MEMBRIDGE_SCANLINE_FRAME_FULL_WIDTH",c, vrlg.MCNTRL_SCANLINE_FRAME_FULL_WIDTH + ba, 0, None, "x393_mcntrl_window_full_width", "wo",     "Set frame full(padded) width")),
            (("X393_MEMBRIDGE_SCANLINE_WINDOW_WH",       c, vrlg.MCNTRL_SCANLINE_WINDOW_WH +        ba, 0, None, "x393_mcntrl_window_width_height", "wo",   "Set frame window size")),
            (("X393_MEMBRIDGE_SCANLINE_WINDOW_X0Y0",     c, vrlg.MCNTRL_SCANLINE_WINDOW_X0Y0 +      ba, 0, None, "x393_mcntrl_window_left_top", "wo",       "Set frame position")),
            (("X393_MEMBRIDGE_SCANLINE_STARTXY",         c, vrlg.MCNTRL_SCANLINE_WINDOW_STARTXY +   ba, 0, None, "x393_mcntrl_window_startx_starty", "wo",  "Set startXY register"))]
750 751 752 753 754
        
        ba = vrlg.MEMBRIDGE_ADDR
        ia = 0
        c =  ""
        sdefines +=[
755
            (("X393_MEMBRIDGE_CTRL",                     c, vrlg.MEMBRIDGE_CTRL +                  ba, 0, None, "x393_membridge_cmd", "wo",                "Issue membridge command")),
756
            (("X393_MEMBRIDGE_STATUS_CNTRL",             c, vrlg.MEMBRIDGE_STATUS_CNTRL +          ba, 0, None, "x393_status_ctrl", "rw",                  "Set membridge status control register")),
757 758 759 760 761
            (("X393_MEMBRIDGE_LO_ADDR64",                c, vrlg.MEMBRIDGE_LO_ADDR64 +             ba, 0, None, "u29", "wo",                               "start address of the system memory range in QWORDs (4 LSBs==0)")),
            (("X393_MEMBRIDGE_SIZE64",                   c, vrlg.MEMBRIDGE_SIZE64 +                ba, 0, None, "u29", "wo",                               "size of the system memory range in QWORDs (4 LSBs==0), rolls over")),
            (("X393_MEMBRIDGE_START64",                  c, vrlg.MEMBRIDGE_START64 +               ba, 0, None, "u29", "wo",                               "start of transfer offset to system memory range in QWORDs (4 LSBs==0)")),
            (("X393_MEMBRIDGE_LEN64",                    c, vrlg.MEMBRIDGE_LEN64 +                 ba, 0, None, "u29", "wo",                               "Full length of transfer in QWORDs")),
            (("X393_MEMBRIDGE_WIDTH64",                  c, vrlg.MEMBRIDGE_WIDTH64 +               ba, 0, None, "u29", "wo",                               "Frame width in QWORDs (last xfer in each line may be partial)")),
762
            (("X393_MEMBRIDGE_CTRL_IRQ",                 c, vrlg.MEMBRIDGE_CTRL_IRQ +              ba, 0, None, "x393_membridge_ctrl_irq", "wo",           "Membridge IRQ control"))]
763 764 765 766 767 768

        ba = vrlg.MCNTRL_PS_ADDR
        ia = 0
        c =  ""
        sdefines +=[
            (('Write-only addresses to PS PIO (Software generated DDR3 memory access sequences)',)),
769 770
            (("X393_MCNTRL_PS_EN_RST",                   c, vrlg.MCNTRL_PS_EN_RST +                ba, 0, None, "x393_ps_pio_en_rst", "wo",                 "Set PS PIO enable and reset")),
            (("X393_MCNTRL_PS_CMD",                      c, vrlg.MCNTRL_PS_CMD +                   ba, 0, None, "x393_ps_pio_cmd", "wo",                    "Set PS PIO commands")),
771
            (("X393_MCNTRL_PS_STATUS_CNTRL",             c, vrlg.MCNTRL_PS_STATUS_CNTRL +          ba, 0, None, "x393_status_ctrl", "rw",                   "Set PS PIO status control register (status update mode)"))]
772 773 774 775 776 777

        #other program status (move to other places?)
        ba = vrlg.MCONTR_PHY_16BIT_ADDR
        ia = 0
        c =  ""
        sdefines +=[
778
            (('Write-only addresses to to program status report mode for memory controller',)),
779 780
            (("X393_MCONTR_PHY_STATUS_CNTRL",            c, vrlg.MCONTR_PHY_STATUS_CNTRL +         ba, 0, None, "x393_status_ctrl", "rw",                    "Set status control register (status update mode)")),
            (("X393_MCONTR_TOP_16BIT_STATUS_CNTRL",      c, vrlg.MCONTR_TOP_16BIT_STATUS_CNTRL +   ba, 0, None, "x393_status_ctrl", "rw",                    "Set status control register (status update mode)")),
781 782 783 784 785 786
        ]
        ba = vrlg.MCNTRL_TEST01_ADDR
        ia = 0
        c =  ""
        sdefines +=[
            (('Write-only addresses to to program status report mode for test channels',)),
787 788 789
            (("X393_MCNTRL_TEST01_CHN2_STATUS_CNTRL",    c, vrlg.MCNTRL_TEST01_CHN2_STATUS_CNTRL + ba, 0, None, "x393_status_ctrl", "rw",                    "Set status control register (status update mode)")),
            (("X393_MCNTRL_TEST01_CHN3_STATUS_CNTRL",    c, vrlg.MCNTRL_TEST01_CHN3_STATUS_CNTRL + ba, 0, None, "x393_status_ctrl", "rw",                    "Set status control register (status update mode)")),
            (("X393_MCNTRL_TEST01_CHN4_STATUS_CNTRL",    c, vrlg.MCNTRL_TEST01_CHN4_STATUS_CNTRL + ba, 0, None, "x393_status_ctrl", "rw",                    "Set status control register (status update mode)")),
790
            (('Write-only addresses for test channels commands',)),
791 792 793
            (("X393_MCNTRL_TEST01_CHN2_MODE",            c, vrlg.MCNTRL_TEST01_CHN2_MODE +         ba, 0, None, "x393_test01_mode", "wo",                    "Set command for test01 channel 2")),
            (("X393_MCNTRL_TEST01_CHN3_MODE",            c, vrlg.MCNTRL_TEST01_CHN3_MODE +         ba, 0, None, "x393_test01_mode", "wo",                    "Set command for test01 channel 3")),
            (("X393_MCNTRL_TEST01_CHN4_MODE",            c, vrlg.MCNTRL_TEST01_CHN4_MODE +         ba, 0, None, "x393_test01_mode", "wo",                    "Set command for test01 channel 4")),
794 795 796 797 798 799
            
]
        #read_all_status
        ba = vrlg.STATUS_ADDR
        ia = 0
        c =  ""
800 801
        fpga_ver=   (1 << vrlg.STATUS_DEPTH) - 1;
        sens_iface= (1 << vrlg.STATUS_DEPTH) - 2;
802 803
        sdefines +=[
            (('Read-only addresses for status information',)),
804 805 806 807 808 809 810
            (("X393_MCONTR_PHY_STATUS",                  c, vrlg.MCONTR_PHY_STATUS_REG_ADDR + ba, 0, None, "x393_status_mcntrl_phy", "ro",                   "Status register for MCNTRL PHY")),
            (("X393_MCONTR_TOP_STATUS",                  c, vrlg.MCONTR_TOP_STATUS_REG_ADDR + ba, 0, None, "x393_status_mcntrl_top", "ro",                   "Status register for MCNTRL requests")),
            (("X393_MCNTRL_PS_STATUS",                   c, vrlg.MCNTRL_PS_STATUS_REG_ADDR +  ba, 0, None, "x393_status_mcntrl_ps", "ro",                    "Status register for MCNTRL software R/W")),
            (("X393_MCNTRL_CHN1_STATUS",                 c, vrlg.MCNTRL_SCANLINE_STATUS_REG_CHN1_ADDR+ba,0,None, "x393_status_mcntrl_lintile", "ro",         "Status register for MCNTRL CHN1 (membridge)")),
            (("X393_MCNTRL_CHN3_STATUS",                 c, vrlg.MCNTRL_SCANLINE_STATUS_REG_CHN3_ADDR+ba,0,None, "x393_status_mcntrl_lintile", "ro",         "Status register for MCNTRL CHN3 (scanline)")),
            (("X393_MCNTRL_CHN2_STATUS",                 c, vrlg.MCNTRL_TILED_STATUS_REG_CHN2_ADDR+ba,0,None,    "x393_status_mcntrl_lintile", "ro",         "Status register for MCNTRL CHN2 (tiled)")),
            (("X393_MCNTRL_CHN4_STATUS",                 c, vrlg.MCNTRL_TILED_STATUS_REG_CHN4_ADDR+ba,0,None,    "x393_status_mcntrl_lintile", "ro",         "Status register for MCNTRL CHN4 (tiled)")),
811
            
812 813 814 815
            (("X393_TEST01_CHN2_STATUS",                 c, vrlg.MCNTRL_TEST01_STATUS_REG_CHN2_ADDR+ba,0,None,   "x393_status_mcntrl_testchn", "ro",         "Status register for test channel 2")),
            (("X393_TEST01_CHN3_STATUS",                 c, vrlg.MCNTRL_TEST01_STATUS_REG_CHN3_ADDR+ba,0,None,   "x393_status_mcntrl_testchn", "ro",         "Status register for test channel 3")),
            (("X393_TEST01_CHN4_STATUS",                 c, vrlg.MCNTRL_TEST01_STATUS_REG_CHN4_ADDR+ba,0,None,   "x393_status_mcntrl_testchn", "ro",         "Status register for test channel 4")),
            (("X393_MEMBRIDGE_STATUS",                   c, vrlg.MEMBRIDGE_STATUS_REG+ba, 0, None,         "x393_status_membridge", "ro",                    "Status register for membridge")),
816 817
            (("X393_FPGA_VERSION",                       c, fpga_ver + ba, 0, None,                         "u32*", "ro",                                    "FPGA bitstream version")),
            (("X393_SENSOR_INTERFACE",                   c, sens_iface + ba, 0, None,                       "u32*", "ro",                                    "Sensor interface 0-parallel 12, 1 - HiSPI 4 lanes")),
818
            ]
819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834
        #Sensor memory status (frame number)        
        ba = vrlg.STATUS_ADDR
        ia = vrlg.MCONTR_SENS_STATUS_INC
        c =  "chn"
        sdefines +=[
            (('Sensor memory channel status)',)),
            (("X393_SENS_MEM_STATUS",                    c, vrlg.MCONTR_SENS_STATUS_BASE + ba, ia, z3, "x393_status_mcntrl_lintile", "ro",  "Status register for sensor memory channel"))]

        #Compressor memory status (frame number)        
        ba = vrlg.STATUS_ADDR
        ia = vrlg.MCONTR_CMPRS_STATUS_INC
        c =  "chn"
        sdefines +=[
            (('Sensor memory channel status)',)),
            (("X393_CMPRS_MEM_STATUS",                   c, vrlg.MCONTR_CMPRS_STATUS_BASE + ba, ia, z3, "x393_status_mcntrl_lintile", "ro",  "Status register for compressor memory channel"))]

835 836 837 838 839 840 841

        #Registers to control sensor channels        
        ba = vrlg.SENSOR_GROUP_ADDR
        ia = vrlg.SENSOR_BASE_INC
        c =  "sens_num"
        sdefines +=[
            (('Write-only control of the sensor channels',)),
842 843
            (("X393_SENS_MODE",                         c, vrlg.SENSOR_CTRL_RADDR +                        ba, ia, z3, "x393_sens_mode", "wo",               "Write sensor channel mode")),
            (("X393_SENSI2C_CTRL",                      c, vrlg.SENSI2C_CTRL_RADDR + vrlg.SENSI2C_CTRL +   ba, ia, z3, "x393_i2c_ctltbl", "wo",              "Control sensor i2c, write i2c LUT")),
844
            (("X393_SENSI2C_STATUS_CTRL",               c, vrlg.SENSI2C_CTRL_RADDR + vrlg.SENSI2C_STATUS + ba, ia, z3, "x393_status_ctrl", "rw",             "Setup sensor i2c status report mode")),
845 846 847 848
            (("X393_SENS_SYNC_MULT",                    c, vrlg.SENS_SYNC_RADDR + vrlg.SENS_SYNC_MULT +    ba, ia, z3, "x393_sens_sync_mult", "wo",          "Configure frames combining")),
            (("X393_SENS_SYNC_LATE",                    c, vrlg.SENS_SYNC_RADDR + vrlg.SENS_SYNC_LATE +    ba, ia, z3, "x393_sens_sync_late", "wo",          "Configure frame sync delay")),
            (("X393_SENSIO_CTRL",                       c, vrlg.SENSIO_RADDR + vrlg.SENSIO_CTRL +          ba, ia, z3, "x393_sensio_ctl", "wo",              "Configure sensor I/O port")),
            (("X393_SENSIO_STATUS_CNTRL",               c, vrlg.SENSIO_RADDR + vrlg.SENSIO_STATUS +        ba, ia, z3, "x393_status_ctrl", "rw",             "Set status control for SENSIO module")),
849
            (("X393_SENSIO_JTAG",                       c, vrlg.SENSIO_RADDR + vrlg.SENSIO_JTAG +          ba, ia, z3, "x393_sensio_jtag", "wo",             "Programming interface for multiplexer FPGA (with X393_SENSIO_STATUS)")),
850 851 852 853 854 855
            (("X393_SENSIO_WIDTH",                      c, vrlg.SENSIO_RADDR + vrlg.SENSIO_WIDTH +         ba, ia, z3, "x393_sensio_width", "rw",            "Set sensor line in pixels (0 - use line sync from the sensor)")),
#            (("X393_SENSIO_DELAYS",                     c, vrlg.SENSIO_RADDR + vrlg.SENSIO_DELAYS +       ba, ia, z3, "x393_sensio_dly", "rw",              "Sensor port input delays (uses 4 DWORDs)")),
            (("X393_SENSIO_TIM0",                       c, vrlg.SENSIO_RADDR + vrlg.SENSIO_DELAYS + 0 +    ba, ia, z3, "x393_sensio_tim0", "rw",             "Sensor port i/o timing configuration, register 0")),
            (("X393_SENSIO_TIM1",                       c, vrlg.SENSIO_RADDR + vrlg.SENSIO_DELAYS + 1 +    ba, ia, z3, "x393_sensio_tim1", "rw",             "Sensor port i/o timing configuration, register 1")),
            (("X393_SENSIO_TIM2",                       c, vrlg.SENSIO_RADDR + vrlg.SENSIO_DELAYS + 2 +    ba, ia, z3, "x393_sensio_tim2", "rw",             "Sensor port i/o timing configuration, register 2")),
            (("X393_SENSIO_TIM3",                       c, vrlg.SENSIO_RADDR + vrlg.SENSIO_DELAYS + 3 +    ba, ia, z3, "x393_sensio_tim3", "rw",             "Sensor port i/o timing configuration, register 3")),
856
            ]
857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875
        #Registers to control sensor channels        
        ba = vrlg.SENSOR_GROUP_ADDR
        ia = vrlg.SENSOR_BASE_INC
        c =  "sens_num"
        sdefines +=[
            (('''I2C command sequencer, block of 16 DWORD slots for absolute frame numbers (modulo 16) and 15 slots for relative ones
// 0 - ASAP, 1 next frame, 14 -14-th next.
// Data written depends on context:
// 1 - I2C register write: index page (MSB), 3 payload bytes. Payload bytes are used according to table and sent
//     after the slave address and optional high address byte. Other bytes are sent in descending order (LSB- last).
//     If less than 4 bytes are programmed in the table the high bytes (starting with the one from the table) are
//     skipped.
//     If more than 4 bytes are programmed in the table for the page (high byte), one or two next 32-bit words 
//     bypass the index table and all 4 bytes are considered payload ones. If less than 4 extra bytes are to be
//     sent for such extra word, only the lower bytes are sent.
//
// 2 - I2C register read: index page, slave address (8-bit, with lower bit 0) and one or 2 address bytes (as programmed
//     in the table. Slave address is always in byte 2 (bits 23:16), byte1 (high register address) is skipped if
//     read address in the table is programmed to be a single-byte one''',)),
876 877
            (("X393_SENSI2C_ABS",            (c,"offset"), vrlg.SENSI2C_ABS_RADDR +                      ba, (ia,1), (z3,z15), "u32*", "wo",                 "Write sensor i2c sequencer")),
            (("X393_SENSI2C_REL",            (c,"offset"), vrlg.SENSI2C_REL_RADDR +                      ba, (ia,1), (z3,z15), "u32*", "wo",                 "Write sensor i2c sequencer"))]
878 879 880 881 882 883 884
        
        #Lens vignetting correction
        ba = vrlg.SENSOR_GROUP_ADDR + vrlg.SENS_LENS_RADDR
        ia = vrlg.SENSOR_BASE_INC
        c =  "sens_num"
        sdefines +=[
            (('Lens vignetting correction (for each sub-frame separately)',)),
885 886 887 888
            (("X393_LENS_HEIGHT0_M1",                   c, 0 +                                            ba, ia, z3, "x393_lens_height_m1", "rw",           "Subframe 0 height minus 1")),
            (("X393_LENS_HEIGHT1_M1",                   c, 1 +                                            ba, ia, z3, "x393_lens_height_m1", "rw",           "Subframe 1 height minus 1")),
            (("X393_LENS_HEIGHT2_M1",                   c, 2 +                                            ba, ia, z3, "x393_lens_height_m1", "rw",           "Subframe 2 height minus 1")),
            (("X393_LENS_CORR_CNH_ADDR_DATA",           c, vrlg.SENS_LENS_COEFF +                         ba, ia, z3, "x393_lens_corr", "wo",                "Combined address/data to write lens vignetting correction coefficients")),
889
            (('Lens vignetting coefficient addresses - use with x393_lens_corr_wo_t (X393_LENS_CORR_CNH_ADDR_DATA)',)),
890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910
            (("X393_LENS_AX",             "", vrlg.SENS_LENS_AX ,             0, None, None, "",    "Address of correction parameter Ax")),
            (("X393_LENS_AX_MASK",        "", vrlg.SENS_LENS_AX_MASK ,        0, None, None, "",    "Correction parameter Ax mask")),
            (("X393_LENS_AY",             "", vrlg.SENS_LENS_AY ,             0, None, None, "",    "Address of correction parameter Ay")),
            (("X393_LENS_AY_MASK",        "", vrlg.SENS_LENS_AY_MASK ,        0, None, None, "",    "Correction parameter Ay mask")),
            (("X393_LENS_C",              "", vrlg.SENS_LENS_C ,              0, None, None, "",    "Address of correction parameter C")),
            (("X393_LENS_C_MASK",         "", vrlg.SENS_LENS_C_MASK ,         0, None, None, "",    "Correction parameter C mask")),
            (("X393_LENS_BX",             "", vrlg.SENS_LENS_BX ,             0, None, None, "",    "Address of correction parameter Bx")),
            (("X393_LENS_BX_MASK",        "", vrlg.SENS_LENS_BX_MASK ,        0, None, None, "",    "Correction parameter Bx mask")),
            (("X393_LENS_BY",             "", vrlg.SENS_LENS_BY ,             0, None, None, "",    "Address of correction parameter By")),
            (("X393_LENS_BY_MASK",        "", vrlg.SENS_LENS_BY_MASK ,        0, None, None, "",    "Correction parameter By mask")),
            (("X393_LENS_SCALE0",         "", vrlg.SENS_LENS_SCALES ,         0, None, None, "",    "Address of correction parameter scale0")),
            (("X393_LENS_SCALE1",         "", vrlg.SENS_LENS_SCALES + 2 ,     0, None, None, "",    "Address of correction parameter scale1")),
            (("X393_LENS_SCALE2",         "", vrlg.SENS_LENS_SCALES + 4 ,     0, None, None, "",    "Address of correction parameter scale2")),
            (("X393_LENS_SCALE3",         "", vrlg.SENS_LENS_SCALES + 6 ,     0, None, None, "",    "Address of correction parameter scale3")),
            (("X393_LENS_SCALES_MASK",    "", vrlg.SENS_LENS_SCALES_MASK ,    0, None, None, "",    "Common mask for scales")),
            (("X393_LENS_FAT0_IN",        "", vrlg.SENS_LENS_FAT0_IN ,        0, None, None, "",    "Address of input fat zero parameter (to subtract from input)")),
            (("X393_LENS_FAT0_IN_MASK",   "", vrlg.SENS_LENS_FAT0_IN_MASK ,   0, None, None, "",    "Mask for fat zero input parameter")),
            (("X393_LENS_FAT0_OUT",       "", vrlg.SENS_LENS_FAT0_OUT,        0, None, None, "",    "Address of output fat zero parameter (to add to output)")),
            (("X393_LENS_FAT0_OUT_MASK",  "", vrlg.SENS_LENS_FAT0_OUT_MASK ,  0, None, None, "",    "Mask for fat zero output  parameters")),
            (("X393_LENS_POST_SCALE",     "", vrlg.SENS_LENS_POST_SCALE ,     0, None, None, "",    "Address of post scale (shift output) parameter")),
            (("X393_LENS_POST_SCALE_MASK","", vrlg.SENS_LENS_POST_SCALE_MASK, 0, None, None, "",    "Mask for post scale parameter"))]
911 912 913 914 915 916
        #Gamma tables (See Python code for examples of the table data generation)
        ba = vrlg.SENSOR_GROUP_ADDR + vrlg.SENS_GAMMA_RADDR
        ia = vrlg.SENSOR_BASE_INC
        c =  "sens_num"
        sdefines +=[
            (('Sensor gamma conversion control (See Python code for examples of the table data generation)',)),
917 918 919 920
            (("X393_SENS_GAMMA_CTRL",                   c, vrlg.SENS_GAMMA_CTRL +                          ba, ia, z3, "x393_gamma_ctl", "rw",               "Gamma module control")),
            (("X393_SENS_GAMMA_TBL",                    c, vrlg.SENS_GAMMA_ADDR_DATA +                     ba, ia, z3, "x393_gamma_tbl", "wo",               "Write sensor gamma table address/data (with autoincrement)")),
            (("X393_SENS_GAMMA_HEIGHT01M1",             c, vrlg.SENS_GAMMA_HEIGHT01 +                      ba, ia, z3, "x393_gamma_height01m1", "rw",        "Gamma module subframes 0,1 heights minus 1")),
            (("X393_SENS_GAMMA_HEIGHT2M1",              c, vrlg.SENS_GAMMA_HEIGHT2 +                       ba, ia, z3, "x393_gamma_height2m1", "rw",         "Gamma module subframe  2 height minus 1"))]
921 922 923 924 925

        #Histogram window controls
        ba = vrlg.SENSOR_GROUP_ADDR
        ia = vrlg.SENSOR_BASE_INC
        c =  "sens_num"
926 927 928
        cs = ("sens_num","sub_chn")
        iam=(vrlg.SENSOR_BASE_INC,vrlg.HISTOGRAM_RADDR_INC)
        z3z3=(z3,z3)
929 930
        sdefines +=[
            (('Windows for histogram subchannels',)),
931 932
            (("X393_HISTOGRAM_LT",                      cs, vrlg.HISTOGRAM_RADDR0 + vrlg.HISTOGRAM_LEFT_TOP +     ba, iam, z3z3, "x393_hist_left_top", "rw",          "Specify histograms left/top")),
            (("X393_HISTOGRAM_WH",                      cs, vrlg.HISTOGRAM_RADDR0 + vrlg.HISTOGRAM_WIDTH_HEIGHT + ba, iam, z3z3, "x393_hist_width_height_m1", "rw",   "Specify histograms width/height")),
933
]
934 935 936 937 938
        ba = vrlg.SENSOR_GROUP_ADDR
        ia = vrlg.SENSOR_BASE_INC
        c =  "subchannel"
        sdefines +=[
            (('DMA control for the histograms. Subchannel here is 4*sensor_port+ histogram_subchannel',)),
939 940
            (("X393_HIST_SAXI_MODE",                    c, vrlg.HIST_SAXI_MODE_ADDR_REL +                  ba,  0, None, "x393_hist_saxi_mode", "rw",       "Histogram DMA operation mode")),
            (("X393_HIST_SAXI_ADDR",                    c, vrlg.HIST_SAXI_ADDR_REL +                       ba,  1, z15,  "x393_hist_saxi_addr", "rw",       "Histogram DMA addresses (in 4096 byte pages)"))]
941 942 943 944 945 946 947 948 949
        #sensors status        
        ba = vrlg.STATUS_ADDR + vrlg.SENSI2C_STATUS_REG_BASE
        ia = vrlg.SENSI2C_STATUS_REG_INC
        c =  "sens_num"
        sdefines +=[
            (('Read-only addresses for sensors status information',)),
            (("X393_SENSI2C_STATUS",                    c, vrlg.SENSI2C_STATUS_REG_REL +      ba, ia, z3, "x393_status_sens_i2c", "ro",                       "Status of the sensors i2c")),
            (("X393_SENSIO_STATUS",                     c, vrlg.SENSIO_STATUS_REG_REL +       ba, ia, z3, "x393_status_sens_io", "ro",                        "Status of the sensor ports I/O pins")),
            ]
950

951 952 953 954 955 956 957 958
        #sensors time measurements (in 1/4 DDR bitrate, now 165MHz)        
        ba = vrlg.STATUS_ADDR + vrlg.SENSOR_TIMING_STATUS_REG_BASE
        ia = vrlg.SENSOR_TIMING_STATUS_REG_INC
        c =  "sens_num"
        sdefines +=[
            (('Read-only addresses for sensors time measurement information',)),
            (("SENSOR_TIMING_STATUS",                   c, 0 +                                ba, ia, z3, "x393_status_sensor_timing", "ro",                  "Measured duration between selected sof/eof/sol/eol")),
            ]
959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979
        #Compressor control
        sdefines +=[
            (('Compressor bitfields values',)),
            (("X393_CMPRS_CBIT_RUN_RST",            "", vrlg.CMPRS_CBIT_RUN_RST ,           0, None, None, "", "Reset compressor, stop immediately")),
            (("X393_CMPRS_CBIT_RUN_DISABLE",        "", 1 ,                                 0, None, None, "", "Disable compression of the new frames, finish any already started")),
            (("X393_CMPRS_CBIT_RUN_STANDALONE",     "", vrlg.CMPRS_CBIT_RUN_STANDALONE ,    0, None, None, "", "Enable compressor, compress single frame from memory (async)")),
            (("X393_CMPRS_CBIT_RUN_ENABLE",         "", vrlg.CMPRS_CBIT_RUN_ENABLE ,        0, None, None, "", "Enable synchronous compression mode")),

            (("X393_CMPRS_CBIT_CMODE_JPEG18",       "", vrlg.CMPRS_CBIT_CMODE_JPEG18 ,      0, None, None, "", "Color 4:2:0 3x3 de-bayer core")),
            (("X393_CMPRS_CBIT_CMODE_MONO6",        "", vrlg.CMPRS_CBIT_CMODE_MONO6 ,       0, None, None, "", "Mono 4:2:0 (6 blocks)")),
            (("X393_CMPRS_CBIT_CMODE_JP46",         "", vrlg.CMPRS_CBIT_CMODE_JP46 ,        0, None, None, "", "jp4, 6 blocks, original")),
            (("X393_CMPRS_CBIT_CMODE_JP46DC",       "", vrlg.CMPRS_CBIT_CMODE_JP46DC ,      0, None, None, "", "jp4, 6 blocks, DC-improved")),
            (("X393_CMPRS_CBIT_CMODE_JPEG20",       "", vrlg.CMPRS_CBIT_CMODE_JPEG20 ,      0, None, None, "", "Color 4:2:0 with 5x5 de-bayer (not implemented)")),
            (("X393_CMPRS_CBIT_CMODE_JP4",          "", vrlg.CMPRS_CBIT_CMODE_JP4 ,         0, None, None, "", "jp4,  4 blocks")),
            (("X393_CMPRS_CBIT_CMODE_JP4DC",        "", vrlg.CMPRS_CBIT_CMODE_JP4DC ,       0, None, None, "", "jp4,  4 blocks, DC-improved")),
            (("X393_CMPRS_CBIT_CMODE_JP4DIFF",      "", vrlg.CMPRS_CBIT_CMODE_JP4DIFF ,     0, None, None, "", "jp4,  4 blocks, differential")),
            (("X393_CMPRS_CBIT_CMODE_JP4DIFFHDR",   "", vrlg.CMPRS_CBIT_CMODE_JP4DIFFHDR,   0, None, None, "", "jp4,  4 blocks, differential, hdr")),
            (("X393_CMPRS_CBIT_CMODE_JP4DIFFDIV2",  "", vrlg.CMPRS_CBIT_CMODE_JP4DIFFDIV2,  0, None, None, "", "jp4,  4 blocks, differential, divide by 2")),
            (("X393_CMPRS_CBIT_CMODE_JP4DIFFHDRDIV2","",vrlg.CMPRS_CBIT_CMODE_JP4DIFFHDRDIV2,0,None, None, "", "jp4,  4 blocks, differential, hdr,divide by 2")),
            (("X393_CMPRS_CBIT_CMODE_MONO1",        "", vrlg.CMPRS_CBIT_CMODE_MONO1 ,       0, None, None, "", "Mono JPEG (not yet implemented)")),
            (("X393_CMPRS_CBIT_CMODE_MONO4",        "", vrlg.CMPRS_CBIT_CMODE_MONO4 ,       0, None, None, "", "Mono, 4 blocks (2x2 macroblocks)")),
980
            (("X393_CMPRS_CBIT_CMODE_RAW",          "", vrlg.CMPRS_CBIT_CMODE_RAW ,         0, None, None, "", "Uncompressed (raw), specify width/height in 16x16 byte macroblocks (in 16-bit 8 pixels wide)")),
981 982 983 984
            (("X393_CMPRS_CBIT_FRAMES_SINGLE",      "", vrlg.CMPRS_CBIT_FRAMES_SINGLE ,     0, None, None, "", "Use single-frame buffer")),
            (("X393_CMPRS_CBIT_FRAMES_MULTI",       "", 1 ,                                 0, None, None, "", "Use multi-frame buffer"))]        
        ba = vrlg.CMPRS_GROUP_ADDR
        ia = vrlg.CMPRS_BASE_INC
985
        c =  "cmprs_chn"
986 987
        sdefines +=[
            (('Compressor control',)),
988
            (("X393_CMPRS_CONTROL_REG",                  c, vrlg.CMPRS_CONTROL_REG +                  ba, ia, z3, "x393_cmprs_mode", "rw",                    "Program compressor channel operation mode")),
989
            (("X393_CMPRS_STATUS",                       c, vrlg.CMPRS_STATUS_CNTRL +                 ba, ia, z3, "x393_status_ctrl", "rw",                   "Setup compressor status report mode")),
990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015
            (("X393_CMPRS_FORMAT",                       c, vrlg.CMPRS_FORMAT +                       ba, ia, z3, "x393_cmprs_frame_format", "rw",            "Compressor frame format")),
            (("X393_CMPRS_COLOR_SATURATION",             c, vrlg.CMPRS_COLOR_SATURATION +             ba, ia, z3, "x393_cmprs_colorsat", "rw",                "Compressor color saturation")),
            (("X393_CMPRS_CORING_MODE",                  c, vrlg.CMPRS_CORING_MODE +                  ba, ia, z3, "x393_cmprs_coring_mode", "rw",             "Select coring mode")),
            (("X393_CMPRS_INTERRUPTS",                   c, vrlg.CMPRS_INTERRUPTS +                   ba, ia, z3, "x393_cmprs_interrupts", "wo",              "Compressor interrupts control (1 - clear, 2 - disable, 3 - enable)")),
            (('_Compressor tables load control',)),
            (('_Several tables can be loaded to the compressor, there are 4 types of them:',)),
            (('_    0:quantization tables - 8 pairs can be loaded and switched at run time,',)),
            (('_    1:coring tables -       8 pairs can be loaded and switched at run time,',)),
            (('_    2:focusing tables -    15 tables can be loaded and switched at run time (16-th table address space',)),
            (('_      is used to program other focusing mode parameters,',)),
            (('_    3:Huffman tables -     1 pair tables can be loaded',)),
            (('_Default tables are loaded with the bitstream file (100% quality for quantization table 0',)),
            (('_Loading a table requires to load address of the beginning of data, it includes table type and optional offset',)),
            (('_when multiple tables of the same type are used. Next the data should be written to the same register address,',)),
            (('_the table address is auto-incremented,',)),
            (('_Data for the tables 0..2 should be combined: two items into a single 32-bit DWORD (little endian), treating',)),
            (('_each item as a 16-bit word. The Huffman table is one item per DWORD. Address offset is calculated in DWORDs',)),
            (('Compressor table types',)),
            (("X393_TABLE_QUANTIZATION_TYPE",            "", vrlg.TABLE_QUANTIZATION_INDEX ,        0, None, None, "", "Quantization table type")),
            (("X393_TABLE_CORING_TYPE",                  "", vrlg.TABLE_CORING_INDEX ,              0, None, None, "", "Coring table type")),
            (("X393_TABLE_FOCUS_TYPE",                   "", vrlg.TABLE_FOCUS_INDEX ,               0, None, None, "", "Focus table type")),
            (("X393_TABLE_HUFFMAN_TYPE",                 "", vrlg.TABLE_HUFFMAN_INDEX ,             0, None, None, "", "Huffman table type")),
            (('Compressor tables control',)),
            (("X393_CMPRS_TABLES_DATA",                   c, vrlg.CMPRS_TABLES + 0 +                 ba, ia, z3, "u32*", "wo",                               "Compressor tables data")),
            (("X393_CMPRS_TABLES_ADDRESS",                c, vrlg.CMPRS_TABLES + 1 +                 ba, ia, z3, "x393_cmprs_table_addr", "wo",              "Compressor tables type/address")),
             ]
1016 1017 1018 1019 1020 1021 1022 1023
        ba = vrlg.STATUS_ADDR
        ia = vrlg.CMPRS_STATUS_REG_INC
        c =  "chn"
        sdefines +=[
            (('Compressor channel status)',)),
            (("X393_CMPRS_STATUS",             c, vrlg.CMPRS_STATUS_REG_BASE + ba, vrlg.CMPRS_STATUS_REG_INC, z3, "x393_cmprs_status", "ro",          "Status of the compressor channel (incl. interrupt")),
            (("X393_CMPRS_HIFREQ",             c, vrlg.CMPRS_HIFREQ_REG_BASE + ba, vrlg.CMPRS_HIFREQ_REG_INC, z3, "u32*", "ro",                       "Focus helper high-frequency amount"))]
        
1024 1025 1026
        ba = vrlg.CMPRS_GROUP_ADDR + vrlg.CMPRS_AFIMUX_RADDR0
        ia = 0
        c =  "afi_port"
1027
        sdefines +=[
1028 1029 1030 1031 1032 1033 1034
            (('Compressor DMA control:',)),
            (('_Camera can be configured to use either 2 AXI HP channels (with 2 compressors served by each one) or to use a single AXI HP channel',)),
            (('_serving all 4 compressor channels through its input ports. Below afi_port (0..3) references to one of the 4 ports of each. Control',)),
            (('_for two AXI HP channels is implemented as separate functions. Currently only the first channel is used',)),
            (("X393_AFIMUX0_EN",                          c, vrlg.CMPRS_AFIMUX_EN +                  ba, 0, None, "x393_afimux_en", "wo",             "AFI MUX 0 global/port run/pause control")),
            (("X393_AFIMUX0_RST",                         c, vrlg.CMPRS_AFIMUX_RST +                 ba, 0, None, "x393_afimux_rst", "rw",            "AFI MUX 0 per-port resets")),
            (("X393_AFIMUX0_REPORT_MODE",                 c, vrlg.CMPRS_AFIMUX_MODE +                ba, 0, None, "x393_afimux_report", "wo",         "AFI MUX 0 readout pointer report mode")),
1035
            (("X393_AFIMUX0_STATUS_CONTROL",              c, vrlg.CMPRS_AFIMUX_STATUS_CNTRL +        ba, 1, z3,   "x393_status_ctrl", "rw",           "AFI MUX 0 status report mode")),
1036 1037 1038 1039 1040 1041 1042 1043
            (("X393_AFIMUX0_SA",                          c, vrlg.CMPRS_AFIMUX_SA_LEN +              ba, 1, z3,   "x393_afimux_sa", "rw",             "AFI MUX 0 DMA buffer start address in 32-byte blocks")),
            (("X393_AFIMUX0_LEN",                         c, vrlg.CMPRS_AFIMUX_SA_LEN + 4 +          ba, 1, z3,   "x393_afimux_len", "rw",            "AFI MUX 0 DMA buffer length in 32-byte blocks"))]
        ba = vrlg.CMPRS_GROUP_ADDR + vrlg.CMPRS_AFIMUX_RADDR1
        sdefines +=[
            (('_Same for the second AXI HP channel (not currently used)',)),
            (("X393_AFIMUX1_EN",                          c, vrlg.CMPRS_AFIMUX_EN +                  ba, 0, None, "x393_afimux_en", "wo",             "AFI MUX 1 global/port run/pause control")),
            (("X393_AFIMUX1_RST",                         c, vrlg.CMPRS_AFIMUX_RST +                 ba, 0, None, "x393_afimux_rst", "rw",            "AFI MUX 1 per-port resets")),
            (("X393_AFIMUX1_REPORT_MODE",                 c, vrlg.CMPRS_AFIMUX_MODE +                ba, 0, None, "x393_afimux_report", "wo",         "AFI MUX 1 readout pointer report mode")),
1044
            (("X393_AFIMUX1_STATUS_CONTROL",              c, vrlg.CMPRS_AFIMUX_STATUS_CNTRL +        ba, 1, z3,   "x393_status_ctrl", "rw",           "AFI MUX 1 status report mode")),
1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055
            (("X393_AFIMUX1_SA",                          c, vrlg.CMPRS_AFIMUX_SA_LEN +              ba, 1, z3,   "x393_afimux_sa", "rw",             "AFI MUX 1 DMA buffer start address in 32-byte blocks")),
            (("X393_AFIMUX1_LEN",                         c, vrlg.CMPRS_AFIMUX_SA_LEN + 4 +          ba, 1, z3,   "x393_afimux_len", "rw",            "AFI MUX 1 DMA buffer length in 32-byte blocks"))]        

        #compressor DMA status        
        ba = vrlg.STATUS_ADDR
        ia = 1
        c =  "afi_port"
        sdefines +=[
            (('Read-only sensors status information (pointer offset and last sequence number)',)),
            (("X393_AFIMUX0_STATUS",                    c, vrlg.CMPRS_AFIMUX_REG_ADDR0 +             ba, ia, z3, "x393_afimux_status", "ro",          "Status of the AFI MUX 0 (including image pointer)")),
            (("X393_AFIMUX1_STATUS",                    c, vrlg.CMPRS_AFIMUX_REG_ADDR1 +             ba, ia, z3, "x393_afimux_status", "ro",          "Status of the AFI MUX 1 (including image pointer)")),
1056
            ]
1057

1058
        #GPIO control - modified to use sequencer so any channel can control it
1059 1060
        ba = vrlg.GPIO_ADDR
        ia = 0
1061
        c =  "sens_chn"
1062 1063 1064 1065 1066 1067 1068 1069
        sdefines +=[
            (('_',)),
            (('_GPIO contol. Each of the 10 pins can be controlled by the software - individually or simultaneously or from any of the 3 masters (other FPGA modules)',)),
            (('_Currently these modules are;',)),
            (('_     A - camsync (intercamera synchronization), uses up to 4 pins ',)),
            (('_     B - reserved (not yet used) and ',)),
            (('_     C - logger (IMU, GPS, images), uses 6 pins, including separate i2c available on extension boards',)),
            (('_If several enabled ports try to contol the same bit, highest priority has port C, lowest - software controlled',)),
1070
            (("X393_GPIO_SET_PINS",                       c,  vrlg.GPIO_SET_PINS +                   ba, 0, z3,   "x393_gpio_set_pins", "wo",       "State of the GPIO pins and seq. number")),
1071
            (("X393_GPIO_STATUS_CONTROL",                 "", vrlg.GPIO_SET_STATUS +                 ba, 0, None, "x393_status_ctrl", "rw",         "GPIO status control mode"))]
1072
        
1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093
        ba = vrlg.STATUS_ADDR
        sdefines +=[
            (('Read-only GPIO pins state',)),
            (("X393_GPIO_STATUS",                         "", vrlg.GPIO_STATUS_REG_ADDR +            ba, 0, None, "x393_gpio_status", "ro",         "State of the GPIO pins and seq. number"))]

        #RTC control
        ba = vrlg.RTC_ADDR
        ia = 0
        c =  ""
        sdefines +=[
            (('RTC control',)),
            (("X393_RTC_USEC",                            "", vrlg.RTC_SET_USEC +                    ba, 0, None, "x393_rtc_usec", "rw",            "RTC microseconds")),
            (("X393_RTC_SEC_SET",                         "", vrlg.RTC_SET_SEC +                     ba, 0, None, "x393_rtc_sec", "rw",             "RTC seconds and set clock")),
            (("X393_RTC_CORR",                            "", vrlg.RTC_SET_CORR +                    ba, 0, None, "x393_rtc_corr", "rw",            "RTC correction (+/- 1/256 full scale)")),
            (("X393_RTC_SET_STATUS",                      "", vrlg.RTC_SET_STATUS +                  ba, 0, None, "x393_status_ctrl", "rw",         "RTC status control mode, write makes a snapshot to be read out"))]
        ba = vrlg.STATUS_ADDR
        sdefines +=[
            (('Read-only RTC state',)),
            (("X393_RTC_STATUS",                         "", vrlg.RTC_STATUS_REG_ADDR +              ba, 0, None, "x393_rtc_status", "ro",          "RTC status reg")),
            (("X393_RTC_STATUS_SEC",                     "", vrlg.RTC_SEC_USEC_ADDR + 0 +            ba, 0, None, "x393_rtc_sec", "ro",             "RTC snapshot seconds")),
            (("X393_RTC_STATUS_USEC",                    "", vrlg.RTC_SEC_USEC_ADDR + 1 +            ba, 0, None, "x393_rtc_usec", "ro",            "RTC snapshot microseconds"))]
1094
        
1095 1096 1097 1098 1099 1100
        #CAMSYNC control
        ba = vrlg.CAMSYNC_ADDR
        ia = 0
        c =  "sens_chn"
        sdefines +=[
            (('CAMSYNC control',)),
1101 1102 1103
            (("X393_CAMSYNC_MODE",                        c, vrlg.CAMSYNC_MODE +                     ba, 0, z3,   "x393_camsync_mode", "wo",        "CAMSYNC mode")),
            (("X393_CAMSYNC_TRIG_SRC",                    c, vrlg.CAMSYNC_TRIG_SRC +                 ba, 0, z3,   "x393_camsync_io",   "wo",        "CAMSYNC trigger source")),
            (("X393_CAMSYNC_TRIG_DST",                    c, vrlg.CAMSYNC_TRIG_DST +                 ba, 0, z3,   "x393_camsync_io",   "wo",        "CAMSYNC trigger destination")),
1104 1105 1106 1107 1108
            (('_Trigger period has special value for small (<255) values written to this register',)),
            (('_    d == 0 - disable (stop periodic mode)',)),
            (('_    d == 1 - single trigger',)),
            (('_    d == 2..255 - set output pulse / input-output serial bit duration (no start generated)',)),
            (('_    d >= 256 - repetitive trigger',)),
1109
            (("X393_CAMSYNC_TRIG_PERIOD",                 c,  vrlg.CAMSYNC_TRIG_PERIOD +             ba, 0, z3,   "u32*", "rw",                     "CAMSYNC trigger period")),
1110 1111
            (("X393_CAMSYNC_TRIG_DELAY",                  c,  vrlg.CAMSYNC_TRIG_DELAY0 +             ba, 1, z3,   "u32*", "rw",                     "CAMSYNC trigger delay"))]
        
1112 1113 1114 1115 1116
        ba = vrlg.CMDFRAMESEQ_ADDR_BASE
        ia = vrlg.CMDFRAMESEQ_ADDR_INC
        c =  "sens_chn"
        sdefines +=[
            (('Command sequencer control',)),
1117
            (('_Controller is programmed through 32 locations. Each register but the control requires two writes:',)),
1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131
            (('_First write - register address (AXI_WR_ADDR_BITS bits), second - register data (32 bits)',)),
            (('_Writing to the contol register (0x1f) resets the first/second counter so the next write will be "first"',)),
            (('_0x0..0xf write directly to the frame number [3:0] modulo 16, except if you write to the frame',)),
            (('_          "just missed" - in that case data will go to the current frame.',)),
            (('_ 0x10 - write seq commands to be sent ASAP',)),
            (('_ 0x11 - write seq commands to be sent after the next frame starts',)), 
            (('_',)),
            (('_ 0x1e - write seq commands to be sent after the next 14 frame start pulses',)),
            (('_ 0x1f - control register:',)),
            (('_     [14] -   reset all FIFO (takes 32 clock pulses), also - stops seq until run command',)),
            (('_     [13:12] - 3 - run seq, 2 - stop seq , 1,0 - no change to run state',)),
            (('_       [1:0] - 0: NOP, 1: clear IRQ, 2 - Clear IE, 3: set IE',)),
            (("X393_CMDFRAMESEQ_CTRL",                    c,  vrlg.CMDFRAMESEQ_CTRL +                ba, ia, z3, "x393_cmdframeseq_mode", "wo",     "CMDFRAMESEQ control register")),
            (("X393_CMDFRAMESEQ_ABS",          (c,"offset"),  vrlg.CMDFRAMESEQ_ABS +                 ba, (ia,1), (z3,z15), "u32*", "wo",            "CMDFRAMESEQ absolute frame address/command")),
1132 1133 1134 1135 1136 1137
            (("X393_CMDFRAMESEQ_REL",          (c,"offset"),  vrlg.CMDFRAMESEQ_REL +                 ba, (ia,1), (z3,z14), "u32*", "wo",            "CMDFRAMESEQ relative frame address/command"))]
        
        ba = 0
        ia = 0
        c =  ""
        sdefines +=[
1138
            (('_Command sequencer multiplexer, provides current frame number for each sensor channel and interrupt status/interrupt masks for them.',)),
1139 1140 1141
            (('_Interrupts and interrupt masks are controlled through channel CMDFRAMESEQ module',)),
            (("X393_CMDSEQMUX_STATUS_CTRL",               "",  vrlg.CMDSEQMUX_ADDR,                      0, None, "x393_status_ctrl", "rw",           "CMDSEQMUX status control mode (status provides current frame numbers)")),
            (("X393_CMDSEQMUX_STATUS",                    "",  vrlg.STATUS_ADDR + vrlg.CMDSEQMUX_STATUS, 0, None, "x393_cmdseqmux_status", "ro",      "CMDSEQMUX status data (frame numbers and interrupts"))]
1142 1143 1144

        sdefines +=[
            (('Event logger',)),
1145
            (('_Event logger configuration/data is written to the module using two 32-bit register locations : data and address.',)),
1146 1147 1148
            (('_Address consists of 2 parts - 2-bit page (configuration, imu, gps, message) and a 5-bit sub-address autoincremented when writing data.',)),
            (('_Register pages:',)),
            (("X393_LOGGER_PAGE_CONF",                    "", 0 ,                                0, None, None, "",    "Logger configuration page")),
1149
            (("X393_LOGGER_PAGE_IMU",                     "", vrlg.LOGGER_PAGE_IMU ,             0, None, None, "",    "Logger IMU parameters page (fist 4 DWORDs are not used)")),
1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169
            (("X393_LOGGER_PAGE_GPS",                     "", vrlg.LOGGER_PAGE_GPS ,             0, None, None, "",    "Logger GPS parameters page")),
            (("X393_LOGGER_PAGE_MSG",                     "", vrlg.LOGGER_PAGE_MSG ,             0, None, None, "",    "Logger MSG (odometer) parameters page")),
            (('_Register configuration addresses (with X393_LOGGER_PAGE_CONF):',)),
            (("X393_LOGGER_PERIOD",                       "", vrlg.LOGGER_PERIOD ,               0, None, None, "",    "IMU period (in SPI clocks, high word 0xffff - use IMU ready)")),
            (("X393_LOGGER_BIT_DURATION",                 "", vrlg.LOGGER_BIT_DURATION ,         0, None, None, "",    "IMU SPI bit duration (in mclk == 50 ns periods?)")),
            (("X393_LOGGER_BIT_HALF_PERIOD",              "", vrlg.LOGGER_BIT_HALF_PERIOD,       0, None, None, "",    "Logger rs232 half bit period (in mclk == 50 ns periods?)")),
            (("X393_LOGGER_CONFIG",                       "", vrlg.LOGGER_CONFIG ,               0, None, None, "",    "Logger IMU parameters page")),
            
            (("X393_LOGGER_STATUS_CTRL",                  "",  vrlg.LOGGER_STATUS,                       0, None,       "x393_status_ctrl", "rw",     "Logger status configuration (to report sample number)")),
            (("X393_LOGGER_DATA",                         "",  vrlg.LOGGER_ADDR + 0,                     0, None,       "x393_logger_data", "wo",     "Logger register write data")),
            (("X393_LOGGER_ADDRESS",                      "",  vrlg.LOGGER_ADDR + 1,                     0, None,       "x393_logger_address", "wo",  "Logger register write page/address")),
            (("X393_LOGGER_STATUS",                       "",  vrlg.STATUS_ADDR + vrlg.LOGGER_STATUS_REG_ADDR, 0, None, "x393_logger_status", "ro",   "Logger status data (sequence number)"))]
#TODO: Add interrupt for the logger?

        #MULT SAXI DMA engine control
        ba = 0
        ia = 0
        c =  "chn"
        sdefines +=[
            (('MULT SAXI DMA engine control. Of 4 channels only one (number 0) is currently used - for the event logger',)),
1170 1171 1172
            (("X393_MULT_SAXI_MODE",                "",  vrlg.MULT_SAXI_CNTRL_ADDR+vrlg.MULT_SAXI_CNTRL_MODE,   0, None, "x393_mult_saxi_mode",       "rw","MULT_SAXI mode register (per-channel enable and run bits)")),
            (("X393_MULT_SAXI_STATUS_CTRL",         "",  vrlg.MULT_SAXI_CNTRL_ADDR+vrlg.MULT_SAXI_CNTRL_STATUS, 0, None, "x393_status_ctrl",          "rw","MULT_SAXI status control mode (status provides current DWORD pointers)")),
            (("X393_MULT_SAXI_INTERRUPTS",          "",  vrlg.MULT_SAXI_CNTRL_ADDR+vrlg.MULT_SAXI_CNTRL_IRQ,    0, None, "x393_mult_saxi_interrupts", "wo","MULT_SAXI per-channel interrupts control (each dibit:nop/reset/disable/enable)")),
1173 1174 1175 1176 1177
            (("X393_MULT_SAXI_BUF_ADDRESS",         c,   vrlg.MULT_SAXI_ADDR + 0,                        2, z3,    "x393_mult_saxi_al",               "wo","MULT_SAXI buffer start address in DWORDS")),
            (("X393_MULT_SAXI_BUF_LEN",             c,   vrlg.MULT_SAXI_ADDR + 1,                        2, z3,    "x393_mult_saxi_al",               "wo","MULT_SAXI buffer length in DWORDS")),
            (("X393_MULT_SAXI_IRQLEN",              c,   vrlg.MULT_SAXI_IRQLEN_ADDR,                     1, z3,    "x393_mult_saxi_irqlen",           "wo","MULT_SAXI lower DWORD address bit to change to generate interrupt")),
            (("X393_MULT_SAXI_POINTERS",            c,   vrlg.STATUS_ADDR + vrlg.MULT_SAXI_POINTERS_REG, 1, z3,    "x393_mult_saxi_al",               "ro","MULT_SAXI current DWORD pointer")),
            (("X393_MULT_SAXI_STATUS",              "",  vrlg.STATUS_ADDR + vrlg.MULT_SAXI_STATUS_REG,   0, None,  "x393_mult_saxi_status",           "ro","MULT_SAXI status with interrupt status"))]
1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207

        #MULTI_CLK global clock generation PLLs
        ba = 0
        ia = 0
        c =  "chn"
        sdefines +=[
            (('MULTI_CLK - global clock generation PLLs. Interface provided for debugging, no interaction is needed for normal operation',)),
            (("X393_MULTICLK_STATUS_CTRL",          "",  vrlg.CLK_ADDR + vrlg.CLK_STATUS,                0, None, "x393_status_ctrl", "rw",           "MULTI_CLK status generation (do not use or do not set auto)")),
            (("X393_MULTICLK_CTRL",                 "",  vrlg.CLK_ADDR + vrlg.CLK_CNTRL,                 0, None, "x393_multiclk_ctl", "rw",          "MULTI_CLK reset and power down control")),
            (("X393_MULTICLK_STATUS",               "",  vrlg.STATUS_ADDR + vrlg.CLK_STATUS_REG_ADDR,    0, None, "x393_multiclk_status", "ro",       "MULTI_CLK lock and toggle state"))]

        #DEBUG ring module
        ba = 0
        ia = 0
        c =  "chn"
        sdefines +=[
            (('Debug ring module',)),
            (('_Debug ring module (when enabled with DEBUG_RING in system_defines.vh) provides low-overhead read/write access to internal test points',)),
            (('_To write data you need to write 32-bit data with x393_debug_shift(u32) multiple times to fill the ring register (length depends on',)),
            (('_implementation), skip this step if only reading from the modules under test is required.',)),
            (('_Exchange data with x393_debug_load(), the data from the ring shift register.',)),
            (('_Write 0xffffffff (or other "magic" data) if the ring length is unknown - this DWORD will appear on the output after the useful data',)),
            (('_Read all data, waiting for status sequence number to be incremented,status mode should be set to auto (3) wor each DWORD certain',)),
            (('_number of times or until the "magic" DWORD appears, writing "magic" to shift out next 32 bits.',)),
            (("X393_DEBUG_STATUS_CTRL",             "",  vrlg.DEBUG_ADDR + vrlg.DEBUG_SET_STATUS,        0, None, "x393_status_ctrl", "rw",           "Debug ring status generation - set to auto(3) if used")),
            (("X393_DEBUG_LOAD",                    "",  vrlg.DEBUG_ADDR + vrlg.DEBUG_LOAD,              0, None, "", "",                             "Debug ring copy shift register to/from tested modules")),
            (("X393_DEBUG_SHIFT",                   "",  vrlg.DEBUG_ADDR + vrlg.DEBUG_SHIFT_DATA,        0, None, "u32*", "wo",                       "Debug ring shift ring by 32 bits")),
            (("X393_DEBUG_STATUS",                  "",  vrlg.STATUS_ADDR + vrlg.DEBUG_STATUS_REG_ADDR,  0, None, "x393_debug_status", "ro",          "Debug read status (watch sequence number)")),
            (("X393_DEBUG_READ",                    "",  vrlg.STATUS_ADDR + vrlg.DEBUG_READ_REG_ADDR,    0, None, "u32*", "ro",                       "Debug read DWORD form ring register"))]

1208 1209 1210 1211 1212 1213 1214 1215
        return sdefines
    
    def define_other_macros(self): # Used mostly for development/testing, not needed for normal camera operation
        ba = vrlg.MCNTRL_SCANLINE_CHN3_ADDR
        c =  ""
        sdefines = []
        sdefines +=[
            (('Write-only addresses to program memory channel 3 (test channel)',)),
1216
            (("X393_MCNTRL_CHN3_SCANLINE_MODE",            c, vrlg.MCNTRL_SCANLINE_MODE +             ba, 0, None, "x393_mcntrl_mode_scan", "wo",             "Set mode register (write last after other channel registers are set)")),
1217
            (("X393_MCNTRL_CHN3_SCANLINE_STATUS_CNTRL",    c, vrlg.MCNTRL_SCANLINE_STATUS_CNTRL +     ba, 0, None, "x393_status_ctrl", "rw",                  "Set status control register (status update mode)")),
1218 1219 1220 1221 1222 1223 1224
            (("X393_MCNTRL_CHN3_SCANLINE_STARTADDR",       c, vrlg.MCNTRL_SCANLINE_STARTADDR +        ba, 0, None, "x393_mcntrl_window_frame_sa", "wo",       "Set frame start address")),
            (("X393_MCNTRL_CHN3_SCANLINE_FRAME_SIZE",      c, vrlg.MCNTRL_SCANLINE_FRAME_SIZE +       ba, 0, None, "x393_mcntrl_window_frame_sa_inc", "wo",   "Set frame size (address increment)")),
            (("X393_MCNTRL_CHN3_SCANLINE_FRAME_LAST",      c, vrlg.MCNTRL_SCANLINE_FRAME_LAST +       ba, 0, None, "x393_mcntrl_window_last_frame_num", "wo", "Set last frame number (number of frames in buffer minus 1)")),
            (("X393_MCNTRL_CHN3_SCANLINE_FRAME_FULL_WIDTH",c, vrlg.MCNTRL_SCANLINE_FRAME_FULL_WIDTH + ba, 0, None, "x393_mcntrl_window_full_width", "wo",     "Set frame full(padded) width")),
            (("X393_MCNTRL_CHN3_SCANLINE_WINDOW_WH",       c, vrlg.MCNTRL_SCANLINE_WINDOW_WH +        ba, 0, None, "x393_mcntrl_window_width_height", "wo",   "Set frame window size")),
            (("X393_MCNTRL_CHN3_SCANLINE_WINDOW_X0Y0",     c, vrlg.MCNTRL_SCANLINE_WINDOW_X0Y0 +      ba, 0, None, "x393_mcntrl_window_left_top", "wo",       "Set frame position")),
            (("X393_MCNTRL_CHN3_SCANLINE_STARTXY",         c, vrlg.MCNTRL_SCANLINE_WINDOW_STARTXY +   ba, 0, None, "x393_mcntrl_window_startx_starty", "wo",  "Set startXY register"))]
1225 1226 1227 1228
        ba = vrlg.MCNTRL_TILED_CHN2_ADDR
        c =  ""
        sdefines +=[
            (('Write-only addresses to program memory channel 2 (test channel)',)),
1229
            (("X393_MCNTRL_CHN2_TILED_MODE",               c, vrlg.MCNTRL_TILED_MODE +                ba, 0, None, "x393_mcntrl_mode_scan", "wo",             "Set mode register (write last after other channel registers are set)")),
1230
            (("X393_MCNTRL_CHN2_TILED_STATUS_CNTRL",       c, vrlg.MCNTRL_TILED_STATUS_CNTRL +        ba, 0, None, "x393_status_ctrl", "rw",                  "Set status control register (status update mode)")),
1231 1232 1233 1234 1235 1236 1237 1238
            (("X393_MCNTRL_CHN2_TILED_STARTADDR",          c, vrlg.MCNTRL_TILED_STARTADDR +           ba, 0, None, "x393_mcntrl_window_frame_sa", "wo",       "Set frame start address")),
            (("X393_MCNTRL_CHN2_TILED_FRAME_SIZE",         c, vrlg.MCNTRL_TILED_FRAME_SIZE +          ba, 0, None, "x393_mcntrl_window_frame_sa_inc", "wo",   "Set frame size (address increment)")),
            (("X393_MCNTRL_CHN2_TILED_FRAME_LAST",         c, vrlg.MCNTRL_TILED_FRAME_LAST +          ba, 0, None, "x393_mcntrl_window_last_frame_num", "wo", "Set last frame number (number of frames in buffer minus 1)")),
            (("X393_MCNTRL_CHN2_TILED_FRAME_FULL_WIDTH",   c, vrlg.MCNTRL_TILED_FRAME_FULL_WIDTH +    ba, 0, None, "x393_mcntrl_window_full_width", "wo",     "Set frame full(padded) width")),
            (("X393_MCNTRL_CHN2_TILED_WINDOW_WH",          c, vrlg.MCNTRL_TILED_WINDOW_WH +           ba, 0, None, "x393_mcntrl_window_width_height", "wo",   "Set frame window size")),
            (("X393_MCNTRL_CHN2_TILED_WINDOW_X0Y0",        c, vrlg.MCNTRL_TILED_WINDOW_X0Y0 +         ba, 0, None, "x393_mcntrl_window_left_top", "wo",       "Set frame position")),
            (("X393_MCNTRL_CHN2_TILED_STARTXY",            c, vrlg.MCNTRL_TILED_WINDOW_STARTXY +      ba, 0, None, "x393_mcntrl_window_startx_starty", "wo",  "Set startXY register")),
            (("X393_MCNTRL_CHN2_TILED_TILE_WHS",           c, vrlg.MCNTRL_TILED_TILE_WHS +            ba, 0, None, "x393_mcntrl_window_tile_whs", "wo",       "Set tile size/step (tiled mode only)"))]
1239 1240 1241 1242
        ba = vrlg.MCNTRL_TILED_CHN4_ADDR
        c =  ""
        sdefines +=[
            (('Write-only addresses to program memory channel 4 (test channel)',)),
1243
            (("X393_MCNTRL_CHN4_TILED_MODE",               c, vrlg.MCNTRL_TILED_MODE +                ba, 0, None, "x393_mcntrl_mode_scan", "wo",             "Set mode register (write last after other channel registers are set)")),
1244
            (("X393_MCNTRL_CHN4_TILED_STATUS_CNTRL",       c, vrlg.MCNTRL_TILED_STATUS_CNTRL +        ba, 0, None, "x393_status_ctrl", "rw",                  "Set status control register (status update mode)")),
1245 1246 1247 1248 1249 1250 1251 1252
            (("X393_MCNTRL_CHN4_TILED_STARTADDR",          c, vrlg.MCNTRL_TILED_STARTADDR +           ba, 0, None, "x393_mcntrl_window_frame_sa", "wo",       "Set frame start address")),
            (("X393_MCNTRL_CHN4_TILED_FRAME_SIZE",         c, vrlg.MCNTRL_TILED_FRAME_SIZE +          ba, 0, None, "x393_mcntrl_window_frame_sa_inc", "wo",   "Set frame size (address increment)")),
            (("X393_MCNTRL_CHN4_TILED_FRAME_LAST",         c, vrlg.MCNTRL_TILED_FRAME_LAST +          ba, 0, None, "x393_mcntrl_window_last_frame_num", "wo", "Set last frame number (number of frames in buffer minus 1)")),
            (("X393_MCNTRL_CHN4_TILED_FRAME_FULL_WIDTH",   c, vrlg.MCNTRL_TILED_FRAME_FULL_WIDTH +    ba, 0, None, "x393_mcntrl_window_full_width", "wo",     "Set frame full(padded) width")),
            (("X393_MCNTRL_CHN4_TILED_WINDOW_WH",          c, vrlg.MCNTRL_TILED_WINDOW_WH +           ba, 0, None, "x393_mcntrl_window_width_height", "wo",   "Set frame window size")),
            (("X393_MCNTRL_CHN4_TILED_WINDOW_X0Y0",        c, vrlg.MCNTRL_TILED_WINDOW_X0Y0 +         ba, 0, None, "x393_mcntrl_window_left_top", "wo",       "Set frame position")),
            (("X393_MCNTRL_CHN4_TILED_STARTXY",            c, vrlg.MCNTRL_TILED_WINDOW_STARTXY +      ba, 0, None, "x393_mcntrl_window_startx_starty", "wo",  "Set startXY register")),
            (("X393_MCNTRL_CHN4_TILED_TILE_WHS",           c, vrlg.MCNTRL_TILED_TILE_WHS +            ba, 0, None, "x393_mcntrl_window_tile_whs", "wo",       "Set tile size/step (tiled mode only)"))]
1253 1254
        return sdefines
    
1255 1256
    def expand_define_maxi0(self, define_tuple, mode, frmt_spcs = None):
        if len(define_tuple)  == 1 :
1257
            return self.expand_define(define_tuple = define_tuple, frmt_spcs = frmt_spcs)
1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273
        elif len(define_tuple)  == 8:
            name, var_name, address, address_inc, var_range, data_type, rw, comment = define_tuple
            if data_type is None:  #just constants, no offset and multiplication
                if (mode == 'defines') or (mode =='func_decl') :
                    return self.expand_define(define_tuple = (name,
                                                              var_name,
                                                              address,
                                                              address_inc,
                                                              var_range,
                                                              data_type,
                                                              rw,
                                                              comment),
                                              frmt_spcs = frmt_spcs)
                else:
                    return ""
            else:
1274 1275 1276 1277
                if isinstance(address_inc,(list,tuple)): # var_name, var_range are also lists/tuples of the same length
                    address_inc = [4 * d for d in address_inc]
                else:
                    address_inc = 4 * address_inc
1278 1279 1280
                #processing sequencer command (have "w" and var_name and var_range = 0..3
                #TODO: Add special character to rw meaning channel applicable
                channelCmd=False
1281 1282
#                if var_name and address_inc and ('w' in rw) and var_range:
                if var_name and ('w' in rw) and var_range:
1283 1284 1285 1286 1287 1288 1289
                    multivar = isinstance(address_inc,(list,tuple))
                    if multivar:
                        if isinstance(var_range[0],(list,tuple)) and (var_range[0][0] == 0) and (var_range[0][1] == 3):
                            channelCmd = True
                    else:
                        if (var_range[0] == 0) and (var_range[1] == 3):
                            channelCmd = True
1290 1291 1292 1293
                if (mode == 'defines') :
                    return self.expand_define(define_tuple = (name,
                                                              var_name,
                                                              address * 4 + self.MAXI0_BASE,
1294
                                                              address_inc, # * 4,
1295 1296 1297 1298 1299 1300
                                                              var_range,
                                                              data_type,
                                                              rw,
                                                              comment),
                                              frmt_spcs = frmt_spcs)
                elif (mode =='func_decl'):
1301 1302
#                    if channelCmd:
#                        print (name,data_type,rw)
1303 1304 1305
                    return self.func_declare (define_tuple = (name,
                                                              var_name,
                                                              address * 4 + self.MAXI0_BASE,
1306
                                                              address_inc, # * 4,
1307 1308 1309 1310
                                                              var_range,
                                                              data_type,
                                                              rw,
                                                              comment),
1311 1312
                                              frmt_spcs = frmt_spcs,
                                              genSeqCmd = channelCmd)
1313 1314 1315
                elif (mode =='func_def'):
                    return self.func_define  (define_tuple = (name,
                                                              var_name,
1316
                                                              address * 4, #  + self.MAXI0_BASE,
1317
                                                              address_inc, # * 4,
1318 1319 1320 1321
                                                              var_range,
                                                              data_type,
                                                              rw,
                                                              comment),
1322 1323
                                              frmt_spcs = frmt_spcs,
                                              genSeqCmd = channelCmd)