Commit f1070dfe authored by Oleg Dzhimiev's avatar Oleg Dzhimiev

Merge remote-tracking branch 'origin/jtag'

parents 82d0a51c 023fb0af
...@@ -6,6 +6,8 @@ obj-$(CONFIG_ELPHEL393) += elphel393-pwr.o ...@@ -6,6 +6,8 @@ obj-$(CONFIG_ELPHEL393) += elphel393-pwr.o
obj-$(CONFIG_ELPHEL393) += elphel393-mem.o obj-$(CONFIG_ELPHEL393) += elphel393-mem.o
obj-$(CONFIG_ELPHELDRVONMICROZED) += elphel393-mem.o obj-$(CONFIG_ELPHELDRVONMICROZED) += elphel393-mem.o
obj-$(CONFIG_ELPHEL393_INIT) += elphel393-init.o obj-$(CONFIG_ELPHEL393_INIT) += elphel393-init.o
obj-$(CONFIG_ELPHEL393) += x393.o
fpgajtag-y := fpgajtag353.o x393.o obj-$(CONFIG_ELPHEL393) += sensor_i2c.o
obj-$(CONFIG_ELPHEL393_EXTERNAL) += fpgajtag.o obj-$(CONFIG_ELPHEL393) += fpgajtag353.o
\ No newline at end of file #fpgajtag-y := fpgajtag353.o x393.o
#obj-$(CONFIG_ELPHEL393_EXTERNAL) += fpgajtag.o
\ No newline at end of file
...@@ -147,15 +147,21 @@ port C 353: ...@@ -147,15 +147,21 @@ port C 353:
#endif #endif
#define FPGA_JTAG_DRIVER_NAME "Elphel (R) model 353 FPGA (Xilinx (R) XC3S1200E) configuration driver" //#define FPGA_JTAG_DRIVER_NAME "Elphel (R) model 353 FPGA (Xilinx (R) XC3S1200E) configuration driver"
#define FPGA_JTAG_MAXMINOR 10 #define FPGA_JTAG_DRIVER_NAME "Elphel (R) model 393 FPGA (Xilinx (R) XC3S1200E) configuration driver"
#define FPGA_JTAG_MAXMINOR 16 // 10
#define JTAG_RAW 0 // raw JTAG access to any FPGA #define JTAG_RAW 0 // raw JTAG access to any FPGA
#define JTAG_MAIN_FPGA 1 // main board FPGA access (10353) #define JTAG_MAIN_FPGA 1 // main board FPGA access (10353)
#define JTAG_SENSOR_FPGA 2 // sensor board FPGA access (10347, 10359) #define JTAG_SENSOR_FPGA 2 // sensor board FPGA access (10347, 10359)
#define JTAG_AUX_FPGA 3 // #define JTAG_AUX_FPGA 3 //
#define JTAG_NCHANNELS 4 //#define JTAG_NCHANNELS 4
#define JTAG_NCHANNELS 16 // 4 << 2
#define JTAG_SENSOR_OFFSET 4 // Sensor ports minors start (4..7) - (2 LSB should be 0)
#define JTAG_SENSOR_CHANNELS 4 // Number of sensor ports for JTAG
#define JTAG_MODE_CLOSED 0 // JTAG channel is closed #define JTAG_MODE_CLOSED 0 // JTAG channel is closed
#define JTAG_MODE_RDID 1 // JTAG channel read ID #define JTAG_MODE_RDID 1 // JTAG channel read ID
...@@ -214,11 +220,11 @@ static struct file_operations fpga_jtag_fops = { ...@@ -214,11 +220,11 @@ static struct file_operations fpga_jtag_fops = {
write: fpga_jtag_write write: fpga_jtag_write
}; };
static int sens_num = 0; //static int sens_num = 0;
// internal functions // internal functions
loff_t fjtag_bitsize (int minor); //loff_t fjtag_bitsize (int minor);
loff_t fjtag_bytesize (int minor); //loff_t fjtag_bytesize (int minor);
int JTAG_channel(int minor); int JTAG_channel(int minor);
void initPortC(void); void initPortC(void);
void set_pgm_mode (int chn, int en); void set_pgm_mode (int chn, int en);
...@@ -243,18 +249,23 @@ int JTAG_process_raw(void); ...@@ -243,18 +249,23 @@ int JTAG_process_raw(void);
int JTAG_channel(int minor) { int JTAG_channel(int minor) {
if ((minor >= FPGA_SJTAG_MINOR_OFFSET) && (minor < (FPGA_SJTAG_MINOR_OFFSET + FPGA_SJTAG_CHANNELS)))
return (minor - FPGA_SJTAG_MINOR_OFFSET) + (JTAG_SENSOR_FPGA << 2);
if ((minor >= FPGA_SJTAG_BOUNDARY_OFFSET) && (minor < (FPGA_SJTAG_BOUNDARY_OFFSET + FPGA_SJTAG_CHANNELS)))
return (minor - FPGA_SJTAG_BOUNDARY_OFFSET) + (JTAG_SENSOR_FPGA << 2);
// maybe will never be used
switch (minor) { switch (minor) {
case FPGA_JTAG_RESET_MINOR : // same as RAW case FPGA_JTAG_RESET_MINOR : // same as RAW
return JTAG_RAW; return JTAG_RAW << 2;
case FPGA_JTAG_MINOR: case FPGA_JTAG_MINOR:
case FPGA_JTAG_BOUNDARY_MINOR: case FPGA_JTAG_BOUNDARY_MINOR:
return JTAG_MAIN_FPGA; return JTAG_MAIN_FPGA << 2;
case FPGA_SJTAG_MINOR: case FPGA_SJTAG_MINOR:
case FPGA_SJTAG_BOUNDARY_MINOR: case FPGA_SJTAG_BOUNDARY_MINOR:
return JTAG_SENSOR_FPGA; return JTAG_SENSOR_FPGA << 2;
case FPGA_AJTAG_MINOR: case FPGA_AJTAG_MINOR:
case FPGA_AJTAG_BOUNDARY_MINOR: case FPGA_AJTAG_BOUNDARY_MINOR:
return JTAG_AUX_FPGA; return JTAG_AUX_FPGA << 2;
} }
return 0; return 0;
} }
...@@ -291,6 +302,7 @@ void JTAG_push_raw (int b) { ...@@ -291,6 +302,7 @@ void JTAG_push_raw (int b) {
raw_fifo_r[raw_fifo_r_wp++]=b; raw_fifo_r[raw_fifo_r_wp++]=b;
if (raw_fifo_r_wp > FJTAG_RAW_RSIZE) raw_fifo_r_wp-=FJTAG_RAW_RSIZE; if (raw_fifo_r_wp > FJTAG_RAW_RSIZE) raw_fifo_r_wp-=FJTAG_RAW_RSIZE;
} }
// TODO: Not updated for 393. Is it needed?
int JTAG_process_raw(void) { int JTAG_process_raw(void) {
unsigned char b0, b1; unsigned char b0, b1;
while (raw_fifo_w_rp != (raw_fifo_w_wp & ~1)) { while (raw_fifo_w_rp != (raw_fifo_w_wp & ~1)) {
...@@ -320,6 +332,7 @@ int JTAG_process_raw(void) { ...@@ -320,6 +332,7 @@ int JTAG_process_raw(void) {
case JTAG_RAW_PGMOFF: case JTAG_RAW_PGMOFF:
set_pgm (raw_chn, 0); set_pgm (raw_chn, 0);
JTAG_push_raw (read_done(raw_chn)); JTAG_push_raw (read_done(raw_chn));
break; // was missing for 353
case JTAG_RAW_PGMON: case JTAG_RAW_PGMON:
set_pgm (raw_chn, 1); set_pgm (raw_chn, 1);
JTAG_push_raw (0xf0); JTAG_push_raw (0xf0);
...@@ -367,7 +380,7 @@ static int fpga_jtag_open(struct inode *inode, struct file *filp) { ...@@ -367,7 +380,7 @@ static int fpga_jtag_open(struct inode *inode, struct file *filp) {
raw_chn=0; raw_chn=0;
break; break;
case FPGA_JTAG_MINOR : case FPGA_JTAG_MINOR :
if ( JTAG_whatopen() & 0x7e) return -EACCES; // none of the channels could be open when opening this file // if ( JTAG_whatopen() & 0x7e) return -EACCES; // none of the channels could be open when opening this file
// JTAG_channels[chn].mode = JTAG_MODE_PGM; // JTAG_channels[chn].mode = JTAG_MODE_PGM;
// JTAG_channels[chn].dbuf = &bitstream_data[0]; // JTAG_channels[chn].dbuf = &bitstream_data[0];
// JTAG_channels[chn].sizew = FJTAG_BUF_SIZE; // JTAG_channels[chn].sizew = FJTAG_BUF_SIZE;
...@@ -386,6 +399,10 @@ static int fpga_jtag_open(struct inode *inode, struct file *filp) { ...@@ -386,6 +399,10 @@ static int fpga_jtag_open(struct inode *inode, struct file *filp) {
// printk ("Camera interrupts disabled\r\n"); // printk ("Camera interrupts disabled\r\n");
// break; // break;
// fall through // fall through
case (FPGA_SJTAG_MINOR_OFFSET + 0): // ugly, fix
case (FPGA_SJTAG_MINOR_OFFSET + 1):
case (FPGA_SJTAG_MINOR_OFFSET + 2):
case (FPGA_SJTAG_MINOR_OFFSET + 3):
case FPGA_SJTAG_MINOR : case FPGA_SJTAG_MINOR :
case FPGA_AJTAG_MINOR : case FPGA_AJTAG_MINOR :
if ( JTAG_whatopen() & 0x7e) return -EACCES; // none of the channels could be open when opening this file if ( JTAG_whatopen() & 0x7e) return -EACCES; // none of the channels could be open when opening this file
...@@ -399,6 +416,10 @@ static int fpga_jtag_open(struct inode *inode, struct file *filp) { ...@@ -399,6 +416,10 @@ static int fpga_jtag_open(struct inode *inode, struct file *filp) {
JTAG_channels[chn].bitsr= FJTAG_IDSIZE; JTAG_channels[chn].bitsr= FJTAG_IDSIZE;
JTAG_openChannel (chn); // configure channel access, reset JTAG and to RUN-TEST/IDLE state JTAG_openChannel (chn); // configure channel access, reset JTAG and to RUN-TEST/IDLE state
break; break;
case (FPGA_SJTAG_BOUNDARY_OFFSET + 0):
case (FPGA_SJTAG_BOUNDARY_OFFSET + 1):
case (FPGA_SJTAG_BOUNDARY_OFFSET + 2):
case (FPGA_SJTAG_BOUNDARY_OFFSET + 3):
case FPGA_JTAG_BOUNDARY_MINOR : case FPGA_JTAG_BOUNDARY_MINOR :
case FPGA_SJTAG_BOUNDARY_MINOR : case FPGA_SJTAG_BOUNDARY_MINOR :
case FPGA_AJTAG_BOUNDARY_MINOR : case FPGA_AJTAG_BOUNDARY_MINOR :
...@@ -416,16 +437,12 @@ static int fpga_jtag_open(struct inode *inode, struct file *filp) { ...@@ -416,16 +437,12 @@ static int fpga_jtag_open(struct inode *inode, struct file *filp) {
break; break;
default: return -EINVAL; default: return -EINVAL;
} }
//D(printk("fpga_jtag_open: chn=%x, JTAG_channels[chn].sizew=%x, JTAG_channels[chn].sizer=%x\r\n", chn,JTAG_channels[chn].sizew, JTAG_channels[chn].sizer) );
//D(printk("fpga_jtag_open: chn=%x, JTAG_channels[chn].bitsw=%x, JTAG_channels[chn].bitsr=%x\r\n", chn,JTAG_channels[chn].bitsw, JTAG_channels[chn].bitsr) );
dev_dbg(NULL, "fpga_jtag_open: chn=%x, JTAG_channels[chn].sizew=%x, JTAG_channels[chn].sizer=%x\r\n", chn, JTAG_channels[chn].sizew, JTAG_channels[chn].sizer); dev_dbg(NULL, "fpga_jtag_open: chn=%x, JTAG_channels[chn].sizew=%x, JTAG_channels[chn].sizer=%x\r\n", chn, JTAG_channels[chn].sizew, JTAG_channels[chn].sizer);
dev_dbg(NULL, "fpga_jtag_open: chn=%x, JTAG_channels[chn].bitsw=%x, JTAG_channels[chn].bitsr=%x\r\n", chn, JTAG_channels[chn].bitsw, JTAG_channels[chn].bitsr); dev_dbg(NULL, "fpga_jtag_open: chn=%x, JTAG_channels[chn].bitsw=%x, JTAG_channels[chn].bitsr=%x\r\n", chn, JTAG_channels[chn].bitsw, JTAG_channels[chn].bitsr);
JTAG_channels[chn].wdirty=0; JTAG_channels[chn].wdirty=0;
// inode->i_size=fjtag_bytesize(p);
inode->i_size=JTAG_channels[chn].sizer; inode->i_size=JTAG_channels[chn].sizer;
minors[p]=p; minors[p]=p;
filp->private_data = &minors[p]; filp->private_data = &minors[p];
//D(printk("fpga_jtag_open: inode->i_size=%x, chn=%x\r\n", (int) inode->i_size, chn) );
dev_dbg(NULL, "fpga_jtag_open: inode->i_size=%x, chn=%x\r\n", (int) inode->i_size, chn); dev_dbg(NULL, "fpga_jtag_open: inode->i_size=%x, chn=%x\r\n", (int) inode->i_size, chn);
return 0; return 0;
} }
...@@ -436,12 +453,14 @@ static int fpga_jtag_release(struct inode *inode, struct file *filp) { ...@@ -436,12 +453,14 @@ static int fpga_jtag_release(struct inode *inode, struct file *filp) {
int res=0; int res=0;
int p = MINOR(inode->i_rdev); int p = MINOR(inode->i_rdev);
int chn= JTAG_channel(p); int chn= JTAG_channel(p);
// reg_intr_vect_rw_mask intr_mask;
//D(printk("fpga_jtag_release: p=%x,chn=%x, wp=0x%x, rp=0x%x\r\n",p,chn, JTAG_channels[chn].wp, JTAG_channels[chn].rp));
dev_dbg(NULL, "fpga_jtag_release: p=%x,chn=%x, wp=0x%x, rp=0x%x\r\n", p, chn, JTAG_channels[chn].wp, JTAG_channels[chn].rp); dev_dbg(NULL, "fpga_jtag_release: p=%x,chn=%x, wp=0x%x, rp=0x%x\r\n", p, chn, JTAG_channels[chn].wp, JTAG_channels[chn].rp);
switch ( p ) { switch ( p ) {
case FPGA_JTAG_RESET_MINOR : // same as RAW - do nothing, raw code should do it on it's own case FPGA_JTAG_RESET_MINOR : // same as RAW - do nothing, raw code should do it on it's own
break; break;
case (FPGA_SJTAG_MINOR_OFFSET + 0): // ugly, fix
case (FPGA_SJTAG_MINOR_OFFSET + 1):
case (FPGA_SJTAG_MINOR_OFFSET + 2):
case (FPGA_SJTAG_MINOR_OFFSET + 3):
case FPGA_JTAG_MINOR : case FPGA_JTAG_MINOR :
case FPGA_SJTAG_MINOR : case FPGA_SJTAG_MINOR :
case FPGA_AJTAG_MINOR : case FPGA_AJTAG_MINOR :
...@@ -456,11 +475,18 @@ static int fpga_jtag_release(struct inode *inode, struct file *filp) { ...@@ -456,11 +475,18 @@ static int fpga_jtag_release(struct inode *inode, struct file *filp) {
//if (chn == JTAG_MAIN_FPGA) fpga_state &=~FPGA_STATE_INITIALIZED; //if (chn == JTAG_MAIN_FPGA) fpga_state &=~FPGA_STATE_INITIALIZED;
break; break;
case (FPGA_SJTAG_BOUNDARY_OFFSET + 0):
case (FPGA_SJTAG_BOUNDARY_OFFSET + 1):
case (FPGA_SJTAG_BOUNDARY_OFFSET + 2):
case (FPGA_SJTAG_BOUNDARY_OFFSET + 3):
case FPGA_JTAG_BOUNDARY_MINOR : case FPGA_JTAG_BOUNDARY_MINOR :
case FPGA_SJTAG_BOUNDARY_MINOR : case FPGA_SJTAG_BOUNDARY_MINOR :
case FPGA_AJTAG_BOUNDARY_MINOR : case FPGA_AJTAG_BOUNDARY_MINOR :
// "dirty"? Send to JTAG // "dirty"? Send to JTAG
if (JTAG_channels[chn].wp >0) JTAG_EXTEST (chn, JTAG_channels[chn].dbuf, JTAG_channels[chn].bitsw); // size in bits if (JTAG_channels[chn].wp >0) {
// D(printk("fpga_jtag_release(), JTAG_channels[%d].wp = 0x%x",chn,JTAG_channels[chn].wp));
JTAG_EXTEST (chn, JTAG_channels[chn].dbuf, JTAG_channels[chn].bitsw); // size in bits
}
JTAG_resetChannel (chn); JTAG_resetChannel (chn);
break; break;
default: return -EINVAL; default: return -EINVAL;
...@@ -480,7 +506,6 @@ static ssize_t fpga_jtag_write(struct file * file, const char * buf, size_t coun ...@@ -480,7 +506,6 @@ static ssize_t fpga_jtag_write(struct file * file, const char * buf, size_t coun
int p = ((int *)file->private_data)[0]; int p = ((int *)file->private_data)[0];
int chn= JTAG_channel(p); int chn= JTAG_channel(p);
size_t size = JTAG_channels[chn].sizew; size_t size = JTAG_channels[chn].sizew;
//D(printk("fpga_jtag_write: p=%x,chn=%x, buf address=%lx count=%lx *offs=%lx, wp=%lx,size=0x%x\r\n",p,chn,(long) buf, (long) count, (long) *off, (long)JTAG_channels[chn].wp, (int) size));
dev_dbg(NULL, "fpga_jtag_write: p=%x,chn=%x, buf address=%lx count=%lx *offs=%lx, wp=%lx,size=0x%x\r\n", p, chn, (long) buf, (long) count, (long) *off, (long)JTAG_channels[chn].wp, (int) size); dev_dbg(NULL, "fpga_jtag_write: p=%x,chn=%x, buf address=%lx count=%lx *offs=%lx, wp=%lx,size=0x%x\r\n", p, chn, (long) buf, (long) count, (long) *off, (long)JTAG_channels[chn].wp, (int) size);
switch (p) { switch (p) {
...@@ -496,6 +521,10 @@ static ssize_t fpga_jtag_write(struct file * file, const char * buf, size_t coun ...@@ -496,6 +521,10 @@ static ssize_t fpga_jtag_write(struct file * file, const char * buf, size_t coun
if (raw_fifo_w_wp > size) raw_fifo_w_wp -= size; if (raw_fifo_w_wp > size) raw_fifo_w_wp -= size;
JTAG_process_raw(); // send all the received data to JTAG - will cause read fifo to get ~1/2 of the number of bytes written JTAG_process_raw(); // send all the received data to JTAG - will cause read fifo to get ~1/2 of the number of bytes written
break; break;
case (FPGA_SJTAG_MINOR_OFFSET + 0): // ugly, fix
case (FPGA_SJTAG_MINOR_OFFSET + 1):
case (FPGA_SJTAG_MINOR_OFFSET + 2):
case (FPGA_SJTAG_MINOR_OFFSET + 3):
case FPGA_JTAG_MINOR : case FPGA_JTAG_MINOR :
case FPGA_SJTAG_MINOR : case FPGA_SJTAG_MINOR :
case FPGA_AJTAG_MINOR : // read configuration data to buffer case FPGA_AJTAG_MINOR : // read configuration data to buffer
...@@ -505,13 +534,17 @@ static ssize_t fpga_jtag_write(struct file * file, const char * buf, size_t coun ...@@ -505,13 +534,17 @@ static ssize_t fpga_jtag_write(struct file * file, const char * buf, size_t coun
*off+=count; *off+=count;
if (*off > JTAG_channels[chn].wp) JTAG_channels[chn].wp= *off; if (*off > JTAG_channels[chn].wp) JTAG_channels[chn].wp= *off;
break; break;
case (FPGA_SJTAG_BOUNDARY_OFFSET + 0):
case (FPGA_SJTAG_BOUNDARY_OFFSET + 1):
case (FPGA_SJTAG_BOUNDARY_OFFSET + 2):
case (FPGA_SJTAG_BOUNDARY_OFFSET + 3):
case FPGA_JTAG_BOUNDARY_MINOR : case FPGA_JTAG_BOUNDARY_MINOR :
case FPGA_SJTAG_BOUNDARY_MINOR : case FPGA_SJTAG_BOUNDARY_MINOR :
case FPGA_AJTAG_BOUNDARY_MINOR : case FPGA_AJTAG_BOUNDARY_MINOR :
if (*off > size) return -EFAULT; if (*off > size) return -EFAULT;
if ((*off + count) > size) count= (size - *off); if ((*off + count) > size) count= (size - *off);
// if ((*off < JTAG_channels[chn].wp) || (JTAG_channels[chn].mode!=JTAG_MODE_EXTEST)) {
if (*off < JTAG_channels[chn].wp) { if (*off < JTAG_channels[chn].wp) {
// D(printk("fpga_jtag_write(), JTAG_channels[%d].wp = 0x%x",chn, JTAG_channels[chn].wp));
JTAG_EXTEST (chn, JTAG_channels[chn].dbuf, JTAG_channels[chn].bitsw); // writing "before" causes EXTEST to fill in boundary scan register JTAG_EXTEST (chn, JTAG_channels[chn].dbuf, JTAG_channels[chn].bitsw); // writing "before" causes EXTEST to fill in boundary scan register
JTAG_channels[chn].wdirty=0; JTAG_channels[chn].wdirty=0;
} }
...@@ -526,8 +559,8 @@ static ssize_t fpga_jtag_write(struct file * file, const char * buf, size_t coun ...@@ -526,8 +559,8 @@ static ssize_t fpga_jtag_write(struct file * file, const char * buf, size_t coun
break; break;
default: return -EINVAL; default: return -EINVAL;
} }
//D(printk("fpga_jtag_write end: p=%x,chn=%x, buf address=%lx count=%lx *offs=%lx, wp=%lx,size=0x%x\r\n",p,chn,(long) buf, (long) count, (long) *off, (long)JTAG_channels[chn].wp, (int) size));
dev_dbg(NULL, "fpga_jtag_write end: p=%x,chn=%x, buf address=%lx count=%lx *offs=%lx, wp=%lx,size=0x%x\r\n", p, chn, (long) buf, (long) count, (long) *off, (long)JTAG_channels[chn].wp, (int) size); dev_dbg(NULL, "fpga_jtag_write end: p=%x,chn=%x, buf address=%lx count=%lx *offs=%lx, wp=%lx,size=0x%x\r\n", p, chn, (long) buf, (long) count, (long) *off, (long)JTAG_channels[chn].wp, (int) size);
//D(printk("fpga_jtag_write end: p=%x,chn=%x, buf address=%lx count=%lx *offs=%lx, wp=%lx,size=0x%x\r\n", p, chn, (long) buf, (long) count, (long) *off, (long)JTAG_channels[chn].wp, (int) size));
return count; return count;
} }
...@@ -538,8 +571,6 @@ ssize_t fpga_jtag_read(struct file * file, char * buf, size_t count, loff_t *off ...@@ -538,8 +571,6 @@ ssize_t fpga_jtag_read(struct file * file, char * buf, size_t count, loff_t *off
int chn= JTAG_channel(p); int chn= JTAG_channel(p);
size_t size = JTAG_channels[chn].sizer; size_t size = JTAG_channels[chn].sizer;
int size_av; // available data int size_av; // available data
// D(printk("fpga_jtag_read from 0x%x, count=0x%x, size=0x%x\n", (int) *off, (int) count, (int) size));
//D(printk("fpga_jtag_read: p=%x,chn=%x, buf address=%lx count=%lx *offs=%lx, rp=%lx,size=0x%x\r\n",p,chn,(long) buf, (long) count, (long) *off, (long)JTAG_channels[chn].rp, (int) size));
dev_dbg(NULL, "fpga_jtag_read: p=%x,chn=%x, buf address=%lx count=%lx *offs=%lx, rp=%lx,size=0x%x\r\n", p, chn,(long) buf, (long) count, (long) *off, (long)JTAG_channels[chn].rp, (int) size); dev_dbg(NULL, "fpga_jtag_read: p=%x,chn=%x, buf address=%lx count=%lx *offs=%lx, rp=%lx,size=0x%x\r\n", p, chn,(long) buf, (long) count, (long) *off, (long)JTAG_channels[chn].rp, (int) size);
switch (p) { switch (p) {
case FPGA_JTAG_RESET_MINOR : // same as RAW - do nothing, raw code should do it on it's own case FPGA_JTAG_RESET_MINOR : // same as RAW - do nothing, raw code should do it on it's own
...@@ -554,6 +585,10 @@ ssize_t fpga_jtag_read(struct file * file, char * buf, size_t count, loff_t *off ...@@ -554,6 +585,10 @@ ssize_t fpga_jtag_read(struct file * file, char * buf, size_t count, loff_t *off
raw_fifo_r_rp+=count; raw_fifo_r_rp+=count;
if (raw_fifo_r_rp > size) raw_fifo_r_rp -= size; if (raw_fifo_r_rp > size) raw_fifo_r_rp -= size;
break; break;
case (FPGA_SJTAG_MINOR_OFFSET + 0): // ugly, fix
case (FPGA_SJTAG_MINOR_OFFSET + 1):
case (FPGA_SJTAG_MINOR_OFFSET + 2):
case (FPGA_SJTAG_MINOR_OFFSET + 3):
case FPGA_JTAG_MINOR : case FPGA_JTAG_MINOR :
case FPGA_SJTAG_MINOR : case FPGA_SJTAG_MINOR :
case FPGA_AJTAG_MINOR : // read configuration data to buffer case FPGA_AJTAG_MINOR : // read configuration data to buffer
...@@ -563,13 +598,16 @@ ssize_t fpga_jtag_read(struct file * file, char * buf, size_t count, loff_t *off ...@@ -563,13 +598,16 @@ ssize_t fpga_jtag_read(struct file * file, char * buf, size_t count, loff_t *off
} }
if (*off > size) return -EFAULT; if (*off > size) return -EFAULT;
if ((*off + count) > size) count= (size - *off); if ((*off + count) > size) count= (size - *off);
//D(printk("fpga_jtag_read_01: p=%x,chn=%x, buf address=%lx count=%lx *offs=%lx, rp=%lx,size=0x%x\r\n",p,chn,(long) buf, (long) count, (long) *off, (long)JTAG_channels[chn].rp, (int) size)); // D(printk("count= 0x%x, pos= 0x%x\n", (int) count, (int)*off)); dev_dbg(NULL, "fpga_jtag_read_01: p=%x,chn=%x, buf address=%lx count=%lx *offs=%lx, rp=%lx,size=0x%x\r\n", p, chn, (long) buf, (long) count, (long) *off, (long)JTAG_channels[chn].rp, (int) size);
dev_dbg(NULL, "fpga_jtag_read_01: p=%x,chn=%x, buf address=%lx count=%lx *offs=%lx, rp=%lx,size=0x%x\r\n", p, chn, (long) buf, (long) count, (long) *off, (long)JTAG_channels[chn].rp, (int) size);
if (copy_to_user(buf,&(JTAG_channels[chn].dbuf[*off]),count)) return -EFAULT; if (copy_to_user(buf,&(JTAG_channels[chn].dbuf[*off]),count)) return -EFAULT;
*off+=count; *off+=count;
JTAG_channels[chn].rp= *off; JTAG_channels[chn].rp= *off;
break; break;
case (FPGA_SJTAG_BOUNDARY_OFFSET + 0):
case (FPGA_SJTAG_BOUNDARY_OFFSET + 1):
case (FPGA_SJTAG_BOUNDARY_OFFSET + 2):
case (FPGA_SJTAG_BOUNDARY_OFFSET + 3):
case FPGA_JTAG_BOUNDARY_MINOR : case FPGA_JTAG_BOUNDARY_MINOR :
case FPGA_SJTAG_BOUNDARY_MINOR : case FPGA_SJTAG_BOUNDARY_MINOR :
case FPGA_AJTAG_BOUNDARY_MINOR : case FPGA_AJTAG_BOUNDARY_MINOR :
...@@ -583,12 +621,7 @@ dev_dbg(NULL, "fpga_jtag_read_01: p=%x,chn=%x, buf address=%lx count=%lx *offs=% ...@@ -583,12 +621,7 @@ dev_dbg(NULL, "fpga_jtag_read_01: p=%x,chn=%x, buf address=%lx count=%lx *offs=%
} }
if (*off > size) return -EFAULT; if (*off > size) return -EFAULT;
if ((*off + count) > size) count= (size - *off); if ((*off + count) > size) count= (size - *off);
//D(printk("fpga_jtag_read_01: p=%x,chn=%x, buf address=%lx count=%lx *offs=%lx, rp=%lx,size=0x%x\r\n",p,chn,(long) buf, (long) count, (long) *off, (long)JTAG_channels[chn].rp, (int) size)); // D(printk("count= 0x%x, pos= 0x%x\n", (int) count, (int)*off)); dev_dbg(NULL, "fpga_jtag_read_01: p=%x,chn=%x, buf address=%lx count=%lx *offs=%lx, rp=%lx,size=0x%x\r\n", p, chn, (long) buf, (long) count, (long) *off, (long)JTAG_channels[chn].rp, (int) size);
dev_dbg(NULL, "fpga_jtag_read_01: p=%x,chn=%x, buf address=%lx count=%lx *offs=%lx, rp=%lx,size=0x%x\r\n", p, chn, (long) buf, (long) count, (long) *off, (long)JTAG_channels[chn].rp, (int) size);
// if (*off < JTAG_channels[chn].rp) {
// JTAG_EXTEST (chn, JTAG_channels[chn].dbuf, JTAG_channels[chn].bitsw); // writing last byte causes EXTEST to fill in boundary scan register
// JTAG_channels[chn].wdirty=0;
// }
if (copy_to_user(buf,&(JTAG_channels[chn].dbuf[*off]),count)) return -EFAULT; if (copy_to_user(buf,&(JTAG_channels[chn].dbuf[*off]),count)) return -EFAULT;
*off+=count; *off+=count;
JTAG_channels[chn].rp= *off; // before rolling over JTAG_channels[chn].rp= *off; // before rolling over
...@@ -599,8 +632,7 @@ dev_dbg(NULL, "fpga_jtag_read_01: p=%x,chn=%x, buf address=%lx count=%lx *offs=% ...@@ -599,8 +632,7 @@ dev_dbg(NULL, "fpga_jtag_read_01: p=%x,chn=%x, buf address=%lx count=%lx *offs=%
break; break;
default: return -EINVAL; default: return -EINVAL;
} }
//D(printk("fpga_jtag_read_end: p=%x,chn=%x, buf address=%lx count=%lx *offs=%lx, rp=%lx,size=0x%x, mode=%x\r\n",p,chn,(long) buf, (long) count, (long) *off, (long)JTAG_channels[chn].rp, (int) size, JTAG_channels[chn].mode)); // D(printk("count= 0x%x, pos= 0x%x\n", (int) count, (int)*off)); dev_dbg(NULL, "fpga_jtag_read_end: p=%x,chn=%x, buf address=%lx count=%lx *offs=%lx, rp=%lx,size=0x%x, mode=%x\r\n", p, chn, (long) buf, (long) count, (long) *off, (long)JTAG_channels[chn].rp, (int) size, JTAG_channels[chn].mode);
dev_dbg(NULL, "fpga_jtag_read_end: p=%x,chn=%x, buf address=%lx count=%lx *offs=%lx, rp=%lx,size=0x%x, mode=%x\r\n", p, chn, (long) buf, (long) count, (long) *off, (long)JTAG_channels[chn].rp, (int) size, JTAG_channels[chn].mode);
return count; return count;
} }
...@@ -608,9 +640,9 @@ dev_dbg(NULL, "fpga_jtag_read_end: p=%x,chn=%x, buf address=%lx count=%lx *offs= ...@@ -608,9 +640,9 @@ dev_dbg(NULL, "fpga_jtag_read_end: p=%x,chn=%x, buf address=%lx count=%lx *offs=
static loff_t fpga_jtag_lseek(struct file * file, loff_t offset, int orig) { static loff_t fpga_jtag_lseek(struct file * file, loff_t offset, int orig) {
/* /*
* orig 0: position from begning of eeprom * orig 0: position from begning of
* orig 1: relative from current position * orig 1: relative from current position
* orig 2: position from last eeprom address * orig 2: position from last address
*/ */
int p = ((int *)file->private_data)[0]; int p = ((int *)file->private_data)[0];
int chn= JTAG_channel(p); int chn= JTAG_channel(p);
...@@ -620,7 +652,7 @@ static loff_t fpga_jtag_lseek(struct file * file, loff_t offset, int orig) { ...@@ -620,7 +652,7 @@ static loff_t fpga_jtag_lseek(struct file * file, loff_t offset, int orig) {
if (size<0) size+=FJTAG_RAW_RSIZE; if (size<0) size+=FJTAG_RAW_RSIZE;
} else size = JTAG_channels[chn].sizew; } else size = JTAG_channels[chn].sizew;
if (JTAG_channels[chn].mode == JTAG_MODE_RDID) size = JTAG_channels[chn].sizer; if (JTAG_channels[chn].mode == JTAG_MODE_RDID) size = JTAG_channels[chn].sizer;
D(printk("fpga_jtag_lseek, fsize= 0x%x\n", (int) size)); dev_dbg(NULL, "fpga_jtag_lseek, fsize= 0x%x\n", (int) size);
switch (orig) { switch (orig) {
case 0: case 0:
file->f_pos = offset; file->f_pos = offset;
...@@ -644,7 +676,7 @@ static loff_t fpga_jtag_lseek(struct file * file, loff_t offset, int orig) { ...@@ -644,7 +676,7 @@ static loff_t fpga_jtag_lseek(struct file * file, loff_t offset, int orig) {
file->f_pos = size; file->f_pos = size;
return (-EOVERFLOW); return (-EOVERFLOW);
} }
D(printk("fpga_jtag_lseek, file->f_pos= 0x%x\n", (int) file->f_pos)); dev_dbg(NULL,"fpga_jtag_lseek, file->f_pos= 0x%x\n", (int) file->f_pos);
return (file->f_pos); return (file->f_pos);
} }
...@@ -700,50 +732,74 @@ inline u32 prep_sensio_status(int sens_num) ...@@ -700,50 +732,74 @@ inline u32 prep_sensio_status(int sens_num)
stat_ctrl.seq_num = stat.seq_num + 1; stat_ctrl.seq_num = stat.seq_num + 1;
stat_ctrl.mode = 1; stat_ctrl.mode = 1;
set_x393_sensio_status_cntrl(stat_ctrl, sens_num); set_x393_sensio_status_cntrl(stat_ctrl, sens_num);
dev_dbg(NULL, "set seq_num = %d, chn = %d", stat_ctrl.seq_num, sens_num); // dev_dbg(NULL, "set seq_num = %d, chn = %d", stat_ctrl.seq_num, sens_num);
return stat_ctrl.seq_num; // Sequence number to expect (wait for) with return data
return stat_ctrl.seq_num;
} }
inline int wait_sensio_status(int chn, u32 seq_num) inline x393_status_sens_io_t wait_sensio_status(int chn, u32 seq_num) // reducing number of hardware reads
{ {
int i; int i;
int ret = 0; int ret = 0;
x393_status_sens_io_t stat; x393_status_sens_io_t stat;
dev_dbg(NULL, "waiting for seq_num = %d, chn = %d", seq_num, chn); // dev_dbg(NULL, "waiting for seq_num = %d, chn = %d", seq_num, chn);
for (i = 0; i < 10; i++) { for (i = 0; i < 10; i++) {
stat = x393_sensio_status(sens_num); stat = x393_sensio_status(chn & 3); // sens_num);
if (stat.seq_num == seq_num) { if (stat.seq_num == seq_num) {
ret = -1; ret = -1;
if (i)
dev_dbg(NULL, "seq_num = %d received after %d wait cycles", seq_num, i); dev_dbg(NULL, "seq_num = %d received after %d wait cycles", seq_num, i);
break; break;
} }
} }
return ret; // return ret;
return stat;
}
inline u32 read_tdo(int sens_num)
{
x393_status_sens_io_t stat;
x393_status_ctrl_t stat_ctrl;
int i;
stat_ctrl.d32 = 0;
stat = x393_sensio_status(sens_num);
stat_ctrl.seq_num = stat.seq_num + 1;
stat_ctrl.mode = 1;
set_x393_sensio_status_cntrl(stat_ctrl, sens_num);
for (i = 0; i < 10; i++) {
stat = x393_sensio_status(sens_num & 3); // sens_num);
if (likely(stat.seq_num == stat_ctrl.seq_num)) {
return stat.xfpgatdo;
}
}
dev_err(NULL,"read_tdo(%d): failed to get expected seq_num in 10 cycles, expected = 0x%x, got 0x%x\n",sens_num,stat_ctrl.seq_num, stat.seq_num);
return stat.xfpgatdo;
} }
// set FPGA in programming/JTAG mode (only for sensor board) // set FPGA in programming/JTAG mode (only for sensor board)
// NOP for the main board FPGA configuration // NOP for the main board FPGA configuration
void set_pgm_mode (int chn, int en) { void set_pgm_mode (int chn, int en) {
u32 seq_num; u32 seq_num;
x393_sensio_jpag_t data; x393_sensio_jtag_t data;
D(printk ("set_pgm_mode (%d,%d)\n",chn,en)); dev_dbg(NULL, "set_pgm_mode (%d,%d)\n",chn,en);
switch (chn) { switch (chn >> 2) {
case JTAG_SENSOR_FPGA: case JTAG_SENSOR_FPGA:
//port_csp0_addr[X313_WA_SENSFPGA] = (en ? (3 << SFPGA_PGMEN_BIT): (SFPGA_RD_SENSPGMPIN | (2 << SFPGA_PGMEN_BIT))) | (2 << SFPGA_TCK_BIT); // turn off TCK (if not turned off already) //port_csp0_addr[X313_WA_SENSFPGA] = (en ? (3 << SFPGA_PGMEN_BIT): (SFPGA_RD_SENSPGMPIN | (2 << SFPGA_PGMEN_BIT))) | (2 << SFPGA_TCK_BIT); // turn off TCK (if not turned off already)
/* ? SFPGA_RD_SENSPGMPIN */ /* ? SFPGA_RD_SENSPGMPIN */
data.d32 = 0;
data.pgmen = (en) ? 1 : 0; data.pgmen = (en) ? 1 : 0;
data.pgmen_set = 1; data.pgmen_set = 1;
data.tck = 0; data.tck = 0;
data.tck_set = 1; data.tck_set = 1;
/* check status register */ /* check status register */
seq_num = prep_sensio_status(sens_num); x393_sensio_jtag(data, chn & 3); // sens_num);
x393_sensio_jtag(data, sens_num);
/* wait for status register update */ /* wait for status register update */
wait_sensio_status(sens_num, seq_num); wait_sensio_status(chn & 3, prep_sensio_status(chn & 3)) ; // Not needed here
break; break;
} }
udelay (2); udelay (2);
...@@ -751,10 +807,10 @@ void set_pgm_mode (int chn, int en) { ...@@ -751,10 +807,10 @@ void set_pgm_mode (int chn, int en) {
void set_pgm (int chn, int pgmon) { void set_pgm (int chn, int pgmon) {
u32 seq_num; u32 seq_num;
x393_sensio_jpag_t data; x393_sensio_jtag_t data;
D(printk ("set_pgm (%d,%d)\n",chn,pgmon)); dev_dbg(NULL, "set_pgm (%d,%d)\n",chn,pgmon);
switch (chn) { switch (chn >> 2) {
case JTAG_MAIN_FPGA: case JTAG_MAIN_FPGA:
#ifdef TEST_DISABLE_CODE #ifdef TEST_DISABLE_CODE
if (pgmon) pc_dout.data &= ~0x80; // set PGM low (active) if (pgmon) pc_dout.data &= ~0x80; // set PGM low (active)
...@@ -766,9 +822,7 @@ void set_pgm (int chn, int pgmon) { ...@@ -766,9 +822,7 @@ void set_pgm (int chn, int pgmon) {
//port_csp0_addr[X313_WA_SENSFPGA] = (2 | (pgmon & 1)) << SFPGA_PROG_BIT; //port_csp0_addr[X313_WA_SENSFPGA] = (2 | (pgmon & 1)) << SFPGA_PROG_BIT;
data.prog= pgmon & 1; data.prog= pgmon & 1;
data.prog_set = 1; data.prog_set = 1;
seq_num = prep_sensio_status(sens_num); x393_sensio_jtag(data, chn >> 2); // sens_num);
x393_sensio_jtag(data, sens_num);
wait_sensio_status(sens_num, seq_num);
break; break;
case JTAG_AUX_FPGA: case JTAG_AUX_FPGA:
break; break;
...@@ -779,9 +833,9 @@ void set_pgm (int chn, int pgmon) { ...@@ -779,9 +833,9 @@ void set_pgm (int chn, int pgmon) {
int read_done (int chn) { int read_done (int chn) {
x393_status_sens_io_t stat; x393_status_sens_io_t stat;
x393_sensio_jpag_t data; x393_sensio_jtag_t data;
switch (chn) { switch (chn >> 2) {
#ifdef TEST_DISABLE_CODE #ifdef TEST_DISABLE_CODE
case JTAG_MAIN_FPGA: case JTAG_MAIN_FPGA:
return ((((REG_RD(gio, regi_gio, r_pc_din)).data & 0x20)==0) ? 0 : 1 ); return ((((REG_RD(gio, regi_gio, r_pc_din)).data & 0x20)==0) ? 0 : 1 );
...@@ -791,7 +845,7 @@ int read_done (int chn) { ...@@ -791,7 +845,7 @@ int read_done (int chn) {
//udelay (1); //udelay (1);
//return (port_csp0_addr[X313__RA__SENSFPGA] >> SFPGA_RD_BIT) & 1 ; //return (port_csp0_addr[X313__RA__SENSFPGA] >> SFPGA_RD_BIT) & 1 ;
stat = x393_sensio_status(sens_num); stat = wait_sensio_status(chn & 3, prep_sensio_status(chn & 3)) ;
return stat.xfpgadone; return stat.xfpgadone;
case JTAG_AUX_FPGA: case JTAG_AUX_FPGA:
return 0; return 0;
...@@ -801,7 +855,8 @@ int read_done (int chn) { ...@@ -801,7 +855,8 @@ int read_done (int chn) {
// send 1..8 bits through JTAG // send 1..8 bits through JTAG
int jtag_send (int chn, int tms, int len, int d) { int jtag_send (int chn, int tms, int len, int d) {
x393_sensio_jpag_t data; int sens_num = chn & 3;
x393_sensio_jtag_t data;
x393_status_sens_io_t stat; x393_status_sens_io_t stat;
u32 seq_num; u32 seq_num;
int i; //,m; int i; //,m;
...@@ -811,8 +866,8 @@ int jtag_send (int chn, int tms, int len, int d) { ...@@ -811,8 +866,8 @@ int jtag_send (int chn, int tms, int len, int d) {
if (i==0) i=8; if (i==0) i=8;
d &= 0xff; d &= 0xff;
d0=d; d0=d;
D( printk("jtag_send(0x%x, 0x%x, 0x%x, 0x%x)\r\n", chn, tms,len,d)); dev_dbg(NULL, "jtag_send(0x%x, 0x%x, 0x%x, 0x%x)\r\n", chn, tms,len,d);
switch (chn) { switch (chn >> 2) {
case JTAG_MAIN_FPGA: case JTAG_MAIN_FPGA:
#ifdef TEST_DISABLE_CODE #ifdef TEST_DISABLE_CODE
pc_dout.data &= ~0x0e; pc_dout.data &= ~0x0e;
...@@ -845,56 +900,36 @@ int jtag_send (int chn, int tms, int len, int d) { ...@@ -845,56 +900,36 @@ int jtag_send (int chn, int tms, int len, int d) {
} }
port_csp0_addr[X313_WA_SENSFPGA] = (2 << SFPGA_TCK_BIT); // TCK=0 port_csp0_addr[X313_WA_SENSFPGA] = (2 << SFPGA_TCK_BIT); // TCK=0
#endif /* TEST_DISABLE_CODE */ #endif /* TEST_DISABLE_CODE */
data.d32 = 0;
data.tck_set = 1;
data.tms_set = 1;
data.tdi_set = 1;
dev_dbg(NULL, "jtag_send(0x%x, 0x%x, 0x%x, 0x%x)\n", chn, tms,len,d);
for ( ; i > 0; i--) { for ( ; i > 0; i--) {
/* TCK = 0 - just a delay; is it really needed? */ /* TCK = 0 - just a delay; is it really needed? */
data.tck = 0; data.tck = 0;
data.tck_set = 1;
seq_num = prep_sensio_status(sens_num);
x393_sensio_jtag(data, sens_num);
wait_sensio_status(sens_num, seq_num);
data.tms = tms & 1; data.tms = tms & 1;
data.tms_set = 1;
data.tdi = ((d <<= 1) >> 8) & 1; data.tdi = ((d <<= 1) >> 8) & 1;
data.tdi_set = 1;
data.tck = 0; data.tck = 0;
data.tck_set = 1;
seq_num = prep_sensio_status(sens_num);
x393_sensio_jtag(data, sens_num);
wait_sensio_status(sens_num, seq_num);
/* TCK = 0 - just a delay; is it really needed? */
data.tck = 0;
data.tck_set = 1;
seq_num = prep_sensio_status(sens_num);
x393_sensio_jtag(data, sens_num); x393_sensio_jtag(data, sens_num);
wait_sensio_status(sens_num, seq_num); /* repeat writel - just a delay; is it really needed? */
// x393_sensio_jtag(data, sens_num);
/* read TDO before TCK pulse */
r = (r << 1) + read_tdo(sens_num); // may to need to read twice to increase delay?
data.tck = 1; data.tck = 1;
data.tck_set = 1; x393_sensio_jtag(data, sens_num); // keep other signals, set TCK == 1
seq_num = prep_sensio_status(sens_num); // x393_sensio_jtag(data, sens_num); // repeat if delay will be needed to increase length of the TCK signal
x393_sensio_jtag(data, sens_num);
wait_sensio_status(sens_num, seq_num);
/* read TDO before TCK pulse */
stat = x393_sensio_status(sens_num);
r = (r << 1) + (stat.xfpgatdo & 1);
/* TCK = 0 - just a delay; is it really needed? */
data.tck = 0; data.tck = 0;
data.tck_set = 1; // x393_sensio_jtag(data, sens_num);
seq_num = prep_sensio_status(sens_num);
x393_sensio_jtag(data, sens_num);
wait_sensio_status(sens_num, seq_num);
} }
data.tck = 0;
data.tck_set = 1;
seq_num = prep_sensio_status(sens_num);
x393_sensio_jtag(data, sens_num); x393_sensio_jtag(data, sens_num);
wait_sensio_status(sens_num, seq_num); dev_dbg(NULL, " ---> %02x\n", r);
break; break;
case JTAG_AUX_FPGA: case JTAG_AUX_FPGA:
...@@ -917,16 +952,17 @@ int jtag_write_bits (int chn, ...@@ -917,16 +952,17 @@ int jtag_write_bits (int chn,
int last, // output last bit with TMS=1 int last, // output last bit with TMS=1
int prev[2]) // if null - don't use int prev[2]) // if null - don't use
{ {
int sens_num = chn & 3;
int i,j; int i,j;
int r=0; int r=0;
int d,d0; int d,d0;
u32 seq_num; // u32 seq_num;
x393_status_sens_io_t stat; x393_status_sens_io_t stat;
x393_sensio_jpag_t data; x393_sensio_jtag_t data;
D( printk("jtag_write_bits(0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\r\n", (int) chn, (int) buf, len, check, last);); dev_dbg(NULL, "jtag_write_bits(0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\r\n", (int) chn, (int) buf, len, check, last);
switch (chn) { switch (chn >> 2) {
case JTAG_MAIN_FPGA: //TODO: save some cycles like for FPGA_SJTAG_MINOR case JTAG_MAIN_FPGA: //TODO: save some cycles like for FPGA_SJTAG_MINOR
#ifdef TEST_DISABLE_CODE #ifdef TEST_DISABLE_CODE
for (i=0; len>0;i++) { for (i=0; len>0;i++) {
...@@ -962,7 +998,7 @@ int jtag_write_bits (int chn, ...@@ -962,7 +998,7 @@ int jtag_write_bits (int chn,
break; break;
case JTAG_SENSOR_FPGA: case JTAG_SENSOR_FPGA:
#ifdef TEST_DISABLE_CODE #ifdef TEST_DISABLE_CODE
port_csp0_addr[X313_WA_SENSFPGA] = SFPGA_RD_TDO; // just in case, it should be in that mode whan calling jtag_write_bits() port_csp0_addr[X313_WA_SENSFPGA] = SFPGA_RD_TDO; // just in case, it should be in that mode when calling jtag_write_bits()
udelay (1); // wait MUX udelay (1); // wait MUX
for (i=0; len>0;i++) { for (i=0; len>0;i++) {
d0=(d=buf[i]); d0=(d=buf[i]);
...@@ -1001,50 +1037,37 @@ int jtag_write_bits (int chn, ...@@ -1001,50 +1037,37 @@ int jtag_write_bits (int chn,
} }
port_csp0_addr[X313_WA_SENSFPGA] = (2 << SFPGA_TCK_BIT); // TCK=0 port_csp0_addr[X313_WA_SENSFPGA] = (2 << SFPGA_TCK_BIT); // TCK=0
#endif /* TEST_DISABLE_CODE */ #endif /* TEST_DISABLE_CODE */
// Can be done once
data.d32 = 0;
data.tck_set = 1;
data.tms_set = 1;
data.tdi_set = 1;
for (i = 0; len > 0; i++) { for (i = 0; len > 0; i++) {
d0 = (d = buf[i]); d0 = (d = buf[i]);
dev_dbg(NULL,"jtag_write_bits(), i=0x%x ", i);
for (j = 0; j < 8; j++) { for (j = 0; j < 8; j++) {
/* TCK = 0 - just a delay; is it really needed? */
data.tck = 0;
data.tck_set = 1;
seq_num = prep_sensio_status(sens_num);
x393_sensio_jtag(data, sens_num);
wait_sensio_status(sens_num, seq_num);
if (len > 0) { if (len > 0) {
if (len == 1 && last) { data.tms = (len == 1 && last)? 1:0 ;
data.tms = 1; data.tms_set = 1; data.tdi = ((d <<= 1) >> 8) & 1;
data.tdi = ((d <<= 1) >> 8) & 1; data.tdi_set = 1; data.tck = 0;
data.tck = 0; data.tck_set = 1;
} else {
data.tdi = ((d <<= 1) >> 8) & 1; data.tdi_set = 1;
data.tms = 0; data.tms_set = 1;
data.tck = 0; data.tck_set = 1;
}
/* TCK = 0 - just a delay; is it really needed? */
data.tck = 0; data.tck_set = 1;
seq_num = prep_sensio_status(sens_num);
x393_sensio_jtag(data, sens_num); x393_sensio_jtag(data, sens_num);
wait_sensio_status(sens_num, seq_num); // x393_sensio_jtag(data, sens_num); // repeat writel() if needed for delay
r = (r << 1) + read_tdo(sens_num);
data.tck = 1; data.tck_set = 1; data.tck = 1;
seq_num = prep_sensio_status(sens_num);
x393_sensio_jtag(data, sens_num); x393_sensio_jtag(data, sens_num);
wait_sensio_status(sens_num, seq_num); // x393_sensio_jtag(data, sens_num); // remove if no delay is needed
/* read TDO before TCK pulse */ data.tck = 0;
stat = x393_sensio_status(sens_num);
r = (r << 1) + (stat.xfpgatdo & 1);
data.tck = 0; data.tck_set = 1;
seq_num = prep_sensio_status(sens_num);
x393_sensio_jtag(data, sens_num); x393_sensio_jtag(data, sens_num);
wait_sensio_status(sens_num, seq_num); // x393_sensio_jtag(data, sens_num);
} else { } else {
r <<= 1; r <<= 1;
} }
len--; len--;
} }
buf[i] = r; buf[i] = r;
dev_dbg(NULL," ===> %02x\n", r);
if (check && ((r ^ (prev[1]>>24)) & 0xff)) { if (check && ((r ^ (prev[1]>>24)) & 0xff)) {
return -((r & 0xff) | ((i+1) << 8)); //readback mismatch return -((r & 0xff) | ((i+1) << 8)); //readback mismatch
} }
...@@ -1053,11 +1076,9 @@ int jtag_write_bits (int chn, ...@@ -1053,11 +1076,9 @@ int jtag_write_bits (int chn,
prev[0]= (prev[0]<<8) | (d0 & 0xff); prev[0]= (prev[0]<<8) | (d0 & 0xff);
} }
} }
data.tck = 1; data.tck_set = 1;
break; break;
case JTAG_AUX_FPGA: case JTAG_AUX_FPGA:
break; break;
} }
return 0; return 0;
} }
...@@ -1074,7 +1095,7 @@ int JTAG_configure (int chn, unsigned char * buf, int len) { ...@@ -1074,7 +1095,7 @@ int JTAG_configure (int chn, unsigned char * buf, int len) {
const unsigned char sync[]={0xff,0xff,0xff,0xff,0xaa,0x99,0x55,0x66}; const unsigned char sync[]={0xff,0xff,0xff,0xff,0xaa,0x99,0x55,0x66};
int skipvfy=8; int skipvfy=8;
D(printk("JTAG_configure: chn=%x, wp=0x%x, rp=0x%x, len=0x%x\r\n",chn, JTAG_channels[chn].wp, JTAG_channels[chn].rp, len)); dev_dbg(NULL, "JTAG_configure: chn=%x, wp=0x%x, rp=0x%x, len=0x%x\r\n",chn, JTAG_channels[chn].wp, JTAG_channels[chn].rp, len);
// all the programming goes here... // all the programming goes here...
// find sync: // find sync:
...@@ -1189,11 +1210,11 @@ int JTAG_configure (int chn, unsigned char * buf, int len) { ...@@ -1189,11 +1210,11 @@ int JTAG_configure (int chn, unsigned char * buf, int len) {
// enable access to JTAG pins. For sensor FPGA that is not possible w/o deprogramming the chip // enable access to JTAG pins. For sensor FPGA that is not possible w/o deprogramming the chip
// leaves in Run-Test-Idle state // leaves in Run-Test-Idle state
int JTAG_openChannel (int chn) { int JTAG_openChannel (int chn) {
D(printk ("JTAG_openChannel (%d)\n",chn)); dev_dbg(NULL, "JTAG_openChannel (%d)\n",chn);
// enable programmimg mode (nop for the 10353 FPGA) // enable programmimg mode (nop for the 10353 FPGA)
set_pgm_mode(chn, 1); set_pgm_mode(chn, 1);
// for shared JTAG/data bus we need to de-program the chip to be able to read JTAG :-( // for shared JTAG/data bus we need to de-program the chip to be able to read JTAG :-(
switch (chn) { switch (chn >> 2) {
case JTAG_SENSOR_FPGA: case JTAG_SENSOR_FPGA:
// reset device // reset device
set_pgm (chn, 1); set_pgm (chn, 1);
...@@ -1205,13 +1226,15 @@ D(printk ("JTAG_openChannel (%d)\n",chn)); ...@@ -1205,13 +1226,15 @@ D(printk ("JTAG_openChannel (%d)\n",chn));
} }
jtag_send(chn, 1, 5, 0 ); // set Test-Logic-Reset state jtag_send(chn, 1, 5, 0 ); // set Test-Logic-Reset state
jtag_send(chn, 0, 1, 0 ); // set Run-Test-Idle state jtag_send(chn, 0, 1, 0 ); // set Run-Test-Idle state
return 0;
} // int JTAG_openChannel (int chn) } // int JTAG_openChannel (int chn)
// //
int JTAG_resetChannel (int chn) { int JTAG_resetChannel (int chn) {
D(printk ("JTAG_resetChannel (%d)\n",chn)); dev_dbg(NULL, "JTAG_resetChannel (%d)\n",chn);
jtag_send(chn, 1, 5, 0 ); // set Test-Logic-Reset state jtag_send(chn, 1, 5, 0 ); // set Test-Logic-Reset state
// disable programmimg mode (nop for the 10353 FPGA) // disable programmimg mode (nop for the 10353 FPGA)
set_pgm_mode(chn, 0); // only for sensor FPGA set_pgm_mode(chn, 0); // only for sensor FPGA
return 0;
} // int JTAG_resetChannel (int chn) } // int JTAG_resetChannel (int chn)
int JTAG_readID (int chn, unsigned char * buf) { int JTAG_readID (int chn, unsigned char * buf) {
...@@ -1290,7 +1313,7 @@ int i; // only in debug ...@@ -1290,7 +1313,7 @@ int i; // only in debug
#ifdef JTAG_DISABLE_IRQ #ifdef JTAG_DISABLE_IRQ
unsigned long flags; unsigned long flags;
#endif #endif
D(printk("buf=%p\n",buf)); dev_dbg(NULL,"JTAG_CAPTURE(): buf=%p\n",buf);
//*************************** NOW DISABLE INTERRUPS FOR THE WHOLE JTAG SEQUENCE *********************** //*************************** NOW DISABLE INTERRUPS FOR THE WHOLE JTAG SEQUENCE ***********************
#ifdef JTAG_DISABLE_IRQ #ifdef JTAG_DISABLE_IRQ
local_irq_save(flags); local_irq_save(flags);
...@@ -1319,7 +1342,12 @@ D(printk("buf=%p\n",buf)); ...@@ -1319,7 +1342,12 @@ D(printk("buf=%p\n",buf));
local_irq_restore(flags); local_irq_restore(flags);
#endif #endif
//*************************** END OF NO INTERRUPS *********************** //*************************** END OF NO INTERRUPS ***********************
D(printk ("\n"); for (i=0; i<((len+7)>>3) ;i++) {printk("%3x ",(int) buf[i]); if ((i & 0xf) == 0xf) printk ("\n");}printk ("\n"); ); dev_dbg(NULL, "\n");
for (i=0; i<((len+7)>>3) ;i++) {
dev_dbg(NULL, "%3x ",(int) buf[i]);
if ((i & 0xf) == 0xf) dev_dbg(NULL, "\n");
}
dev_dbg(NULL, "\n");
data_modified=0; data_modified=0;
return 0; return 0;
...@@ -1340,7 +1368,8 @@ int i; // only in debug ...@@ -1340,7 +1368,8 @@ int i; // only in debug
local_irq_save(flags); local_irq_save(flags);
//local_irq_disable(); //local_irq_disable();
#endif #endif
D(printk("EXTEST: buf=%p, len=0x%x\n",buf,len)); //D(printk("EXTEST: buf=%p, len=0x%x\n",buf,len));
//D(printk ("\n"); for (i=0; i<((len+7)>>3) ;i++) {printk("%3x ",(int) buf[i]); if ((i & 0xf) == 0xf) printk ("\n");}printk ("\n"); );
// jtag_send(chn, 1, 5, 0 ); //step 1 - set Test-Logic-Reset state // jtag_send(chn, 1, 5, 0 ); //step 1 - set Test-Logic-Reset state
// jtag_send(chn, 0, 1, 0 ); //step 2 - set Run-Test-Idle state // jtag_send(chn, 0, 1, 0 ); //step 2 - set Run-Test-Idle state
...@@ -1360,7 +1389,7 @@ D(printk("EXTEST: buf=%p, len=0x%x\n",buf,len)); ...@@ -1360,7 +1389,7 @@ D(printk("EXTEST: buf=%p, len=0x%x\n",buf,len));
#ifdef JTAG_DISABLE_IRQ #ifdef JTAG_DISABLE_IRQ
local_irq_restore(flags); local_irq_restore(flags);
#endif #endif
D(printk ("\n"); for (i=0; i<((len+7)>>3) ;i++) {printk("%3x ",(int) buf[i]); if ((i & 0xf) == 0xf) printk ("\n");}printk ("\n"); ); // D(printk ("\n"); for (i=0; i<((len+7)>>3) ;i++) {printk("%3x ",(int) buf[i]); if ((i & 0xf) == 0xf) printk ("\n");}printk ("\n"); );
return 0; return 0;
} //int JTAG_EXTEST (int chn, unsigned char * buf, int len) } //int JTAG_EXTEST (int chn, unsigned char * buf, int len)
...@@ -1395,6 +1424,6 @@ module_exit(fpga_jtag_exit); ...@@ -1395,6 +1424,6 @@ module_exit(fpga_jtag_exit);
module_init(fpga_jtag_init); module_init(fpga_jtag_init);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_AUTHOR("Andrey Filippov <andrey@elphel.com>."); MODULE_AUTHOR("Andrey Filippov <andrey@elphel.com>");
MODULE_DESCRIPTION(FPGA_JTAG_DRIVER_NAME); MODULE_DESCRIPTION(FPGA_JTAG_DRIVER_NAME);
/*******************************************************************************
* FILE NAME : sensor_i2c.c
* DESCRIPTION: Interface to FPGA-based i2c sequencer for sensor ports
* Copyright 2016 (C) Elphel, Inc.
* -----------------------------------------------------------------------------*
*
* 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/>.
*******************************************************************************/
/****************** INCLUDE FILES SECTION ***********************************/
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/string.h>
//#include <linux/poll.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/spinlock.h>
//#include <linux/spinlock_types.h>
#include <asm/io.h>
//#include <asm/system.h>
#include <asm/irq.h>
#include <elphel/driver_numbers.h>
#include <asm/uaccess.h>
#include "x393.h"
#include "sensor_i2c.h"
//------------------
#include <asm/page.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_fdt.h>
#include <linux/of_net.h>
#include <linux/platform_device.h>
#include <linux/sysfs.h>
#define SYSFS_PERMISSIONS 0644 /* default permissions for sysfs files */
#define SYSFS_READONLY 0444
#define SYSFS_WRITEONLY 0222
#define DRV_NAME "elphel_sensor_i2c"
//------------------
#if 0
#include <linux/fs.h>
/**
* alloc_chrdev_region() - register a range of char device numbers
* @dev: output parameter for first assigned number
* @baseminor: first of the requested range of minor numbers
* @count: the number of minor numbers required
* @name: the name of the associated device or driver
*
* Allocates a range of char device numbers. The major number will be
* chosen dynamically, and returned (along with the first minor number)
* in @dev. Returns zero or a negative error code.
*/
int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count,
const char *name)
{
struct char_device_struct *cd;
cd = __register_chrdev_region(0, baseminor, count, name);
if (IS_ERR(cd))
return PTR_ERR(cd);
*dev = MKDEV(cd->major, cd->baseminor);
return 0;
}
#endif
// Number of channels is hard-wired to 4
static u32 free_i2c_groups[4];
static u32 free_i2c_pages [32];
static DEFINE_SPINLOCK(lock);
static u32 i2c_pages_shadow[1024]; // Mostly for debugging to analyze i2c pages allocation
static int sysfs_page[4]; // when positive - page locked for exclusive access
/* Mark all i2c pages for each channel as free */
void i2c_page_alloc_init(void){
int i;
for (i = 0; i < sizeof(free_i2c_groups)/sizeof(free_i2c_groups[0]); i++) free_i2c_groups[i] = 0xff000000;
for (i = 0; i < sizeof(free_i2c_pages)/ sizeof(free_i2c_pages[0]); i++) free_i2c_pages[i] = 0xffffffff;
for (i = 0; i < sizeof(i2c_pages_shadow)/sizeof(i2c_pages_shadow[0]); i++) i2c_pages_shadow[i] = 0;
for (i = 0; i < sizeof(sysfs_page)/sizeof(sysfs_page[0]); i++) sysfs_page[i] = -1;
}
/* Reserve i2c page (1 of 256 for a sensor port)*/
int i2c_page_alloc(int chn){
int g, b;
u32 * fb;
spin_lock(&lock);
g = __builtin_clz(free_i2c_groups[chn]);
if (unlikely(g > 7)) {
spin_unlock(&lock);
return -ENOMEM; // no free i2c pages left
}
fb = free_i2c_pages + ((chn << 3) + g);
b = __builtin_clz(*fb);
*fb &= ~ (1 << (31-b));
if (unlikely(*fb == 0)){
free_i2c_groups[chn] &= ~(1 << (31 - g));
}
spin_unlock(&lock);
return (g << 5) + b;
}
/* Free i2c page */
void i2c_page_free(int chn, int page){
int g = page >> 5;
int b = page & 0x1f;
u32 * fb = free_i2c_pages + ((chn << 3) + g);
spin_lock(&lock);
free_i2c_groups[chn] |= 1 << (31 - g);
*fb |= 1 << (31-b);
spin_unlock(&lock);
}
/* Set i2c table entry to raw data (will just overwrite tbl_mode = 2)*/
void set_sensor_i2c_raw(int chn,
int page, // index in lookup table
u32 data) { // Bit delay - number of mclk periods in 1/4 of the SCL period
x393_i2c_ctltbl_t tb_data, tb_addr;
tb_addr.d32 = 0;
tb_addr.tbl_mode = 3;
tb_data.d32 = data;
tb_data.tbl_mode = 2; //
/* Table address and data should not interleave with others */
spin_lock(&lock);
x393_sensi2c_ctrl (tb_addr, chn);
x393_sensi2c_ctrl (tb_data, chn);
spin_unlock(&lock);
i2c_pages_shadow[(chn << 8) + page] =tb_data.d32;
}
/* Set i2c table entry for write operation */
void set_sensor_i2c_wr(int chn,
int page, // index in lookup table
int sa, // slave address (7 bit)
int rah, // High byte of the i2c register address
int num_bytes, //Number of bytes to write (1..10)
int bit_delay) { // Bit delay - number of mclk periods in 1/4 of the SCL period
x393_i2c_ctltbl_t tb_data, tb_addr;
tb_addr.d32 = 0;
tb_addr.tbl_mode = 3;
tb_data.d32 = 0;
tb_data.rah = rah;
tb_data.rnw = 0;
tb_data.sa = sa;
tb_data.nbwr = num_bytes;
tb_data.dly = bit_delay;
tb_data.tbl_mode = 2;
/* Table address and data should not interleave with others */
spin_lock(&lock);
x393_sensi2c_ctrl (tb_addr, chn);
x393_sensi2c_ctrl (tb_data, chn);
spin_unlock(&lock);
i2c_pages_shadow[(chn << 8) + page] =tb_data.d32;
}
/* Set i2c table entry for read operation */
void set_sensor_i2c_rd(int chn,
int page, // index in lookup table
int two_byte_addr, // Number of address bytes (0 - one byte, 1 - two bytes)
int num_bytes, // Number of bytes to read (1..8, 0 means 8)
int bit_delay) { // Bit delay - number of mclk periods in 1/4 of the SCL period
x393_i2c_ctltbl_t tb_data, tb_addr;
tb_addr.d32 = 0;
tb_addr.tbl_mode = 3;
tb_data.d32 = 0;
tb_data.rnw = 1;
tb_data.nabrd = two_byte_addr;
tb_data.nbrd = num_bytes;
tb_data.dly = bit_delay;
tb_data.tbl_mode = 2;
/* Table address and data should not interleave with others */
spin_lock(&lock);
x393_sensi2c_ctrl (tb_addr, chn);
x393_sensi2c_ctrl (tb_data, chn);
spin_unlock(&lock);
i2c_pages_shadow[(chn << 8) + page] =tb_data.d32;
}
/*
// Write i2c command to the i2c command sequencer
// 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
*/
/* Write one or multiple DWORDs to i2c relative (modulo16) address. Use offs = 0 for immediate (ASAP) command */
/* Length of data is determined by the page data already preset */
int write_sensor_i2c_rel (int chn,
int offs, // 4 bits
u32 * data){
x393_i2c_ctltbl_t tb_data;
int len;
int i;
tb_data.d32 = i2c_pages_shadow[(chn <<8) + (data[0] >> 24)];
if (tb_data.tbl_mode !=2) return -1;
len = (tb_data.rnw )? 1:((tb_data.nbwr + 5) >> 2); // read mode - always 1 DWORD, write - 1..3
if (len > 1) {
spin_lock(&lock);
for (i = 0; i <len; i++){
x393_sensi2c_rel (data[i], chn, offs);
}
} else {
x393_sensi2c_rel (data[0], chn, offs);
}
spin_unlock(&lock);
return 0;
}
int write_sensor_i2c_abs (int chn,
int offs, // 4 bits
u32 * data){
x393_i2c_ctltbl_t tb_data;
int len;
int i;
tb_data.d32 = i2c_pages_shadow[(chn <<8) + (data[0] >> 24)];
if (tb_data.tbl_mode !=2) return -1;
len = (tb_data.rnw )? 1:((tb_data.nbwr + 5) >> 2); // read mode - always 1 DWORD, write - 1..3
if (len > 1) {
spin_lock(&lock);
for (i = 0; i <len; i++){
x393_sensi2c_abs (data[i], chn, offs);
}
} else {
x393_sensi2c_abs (data[0], chn, offs);
}
spin_unlock(&lock);
return 0;
}
/* Write sensor 16 bit (or 8 bit as programmed in the table) data in immediate mode */
void write_sensor_reg16 (int chn,
int page, // page (8 bits)
int addr, // low 8 bits
u32 data){ // 16 or 8-bit data (LSB aligned)
u32 dw = ((page & 0xff) << 24) | ((addr & 0xff) << 16) | (data & 0xffff);
x393_sensi2c_rel (dw, chn, 0);
}
/* Initiate sensor i2c read in immediate mode (data itself has to be read from FIFO with read_sensor_i2c_fifo)*/
void read_sensor_i2c (int chn,
int page, // page (8 bits)
int sa7, // 7-bit i2c slave address
int addr){ // 8/16 bit address
u32 dw = ((page & 0xff) << 24) | (sa7 << 17) | (addr & 0xffff);
x393_sensi2c_rel (dw, chn, 0);
}
//void x393_sensi2c_rel (u32 d, int sens_num, int offset){writel(d, mmio_ptr + (0x1080 + 0x40 * sens_num + 0x1 * offset));} // Write sensor i2c sequencer
/* Read next byte from the channel i2c FIFO. Return byte or -1 if no data available */
/* Sensor channel status should be in auto update mode (3) */
int read_sensor_i2c_fifo(int chn){
int fifo_lsb, rslt,i;
x393_i2c_ctltbl_t i2c_cmd;
x393_status_sens_i2c_t status = x393_sensi2c_status (chn);
if (!status.i2c_fifo_nempty) return -1; // No data available
fifo_lsb = status.i2c_fifo_lsb;
rslt = status.i2c_fifo_dout;
// Advance FIFO readout pointer
i2c_cmd.d32 = 0;
i2c_cmd.next_fifo_rd = 1; // tbl_mode is 0 already
x393_sensi2c_ctrl (i2c_cmd, chn);
for (i = 0; i < 10; i++) {
status = x393_sensi2c_status(chn);
if (likely(status.i2c_fifo_lsb != fifo_lsb)) break;
}
return rslt;
}
// ======================================
// SYSFS
/* Get channelo number from the last character of the attribute name*/
static int get_channel_from_name(struct device_attribute *attr){
int reg = 0;
sscanf(attr->attr.name + (strlen(attr->attr.name)-1), "%du", &reg);
return reg;
}
static ssize_t get_i2c_page_alloc(struct device *dev, struct device_attribute *attr, char *buf)
{
int chn = get_channel_from_name(attr) ;
int page;
// if (sysfs_page[chn]>=0)
// return -EBUSY;
page= i2c_page_alloc(chn);
if (page <0)
return -ENOMEM;
sysfs_page[chn] = page;
return sprintf(buf,"%d\n",page);
}
static ssize_t free_i2c_page(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
int chn = get_channel_from_name(attr) ;
int page;
sscanf(buf, "%i", &page);
page &= 0xff;
// if (sysfs_page[chn] >= 0)
// i2c_page_free(chn, page);
// sysfs_page[chn] = -1; // free
i2c_page_free(chn, page);
return count;
}
/* Set/get page number for reading */
static ssize_t set_i2c_page_inuse(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
int chn = get_channel_from_name(attr) ;
int page;
sscanf(buf, "%i", &page);
sysfs_page[chn] = page & 0xff;
return count;
}
static ssize_t get_i2c_page_inuse(struct device *dev, struct device_attribute *attr, char *buf)
{
int chn = get_channel_from_name(attr) ;
return sprintf(buf,"%d\n",sysfs_page[chn]);
}
// Get i2c table data as raw data (hex)
static ssize_t get_i2c_tbl_raw(struct device *dev, struct device_attribute *attr, char *buf)
{
int chn = get_channel_from_name(attr) ;
int page = sysfs_page[chn]; // currently selected page for sysfs reads
if (page < 0)
return -ENXIO; /* No such device or address */
return sprintf(buf,"0x%08x\n",i2c_pages_shadow[(chn << 8) + (page &0xff)]);
}
static ssize_t set_i2c_tbl_raw(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
int chn = get_channel_from_name(attr) ;
int ni, page, data;
ni = sscanf(buf, "%i %i", &page, &data);
if (ni < 2)
dev_err(dev, "Requires 2 parameters: page, data\n");
return -EINVAL;
set_sensor_i2c_raw(chn,
page & 0xff, // index in lookup table
(u32) data); // Bit delay - number of mclk periods in 1/4 of the SCL period
return count;
}
// Get/parse i2c table (hex)
static ssize_t get_i2c_tbl_human(struct device *dev, struct device_attribute *attr, char *buf)
{
x393_i2c_ctltbl_t tb_data;
int chn = get_channel_from_name(attr) ;
int page = sysfs_page[chn]; // currently selected page for sysfs reads
if (page < 0)
return -ENXIO; /* No such device or address */
tb_data.d32 = i2c_pages_shadow[(chn << 8) + (page &0xff)];
if (tb_data.rnw){
return sprintf(buf,"Read entry: chn=%d page=%d(0x%x) two_byte_addr=%d number bytes to read=%d bit_duration=%d\n",
chn, page,page, tb_data.nabrd,tb_data.nabrd,tb_data.nbrd, tb_data.dly);
} else {
return sprintf(buf,"Write entry: chn=%d page=%d(0x%x) sa=0x%02x rah=0x%02x nbw=%d bit_duration=%d\n",
chn, page,page,tb_data.sa,tb_data.rah,tb_data.nbwr, tb_data.dly);
}
}
static ssize_t set_i2c_tbl_wr_human(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
int chn = get_channel_from_name(attr) ;
int ni, page, rah,sa7,nbwr,dly;
ni = sscanf(buf, "%i %i %i %i %i", &page, &sa7, &rah, &nbwr, &dly);
if (ni < 2)
dev_err(dev, "Requires 5 parameters: page, slave address (7 bit), high reg address byte, bytes to write (1..10), 1/4 scl period in mclk\n");
return -EINVAL;
set_sensor_i2c_wr(chn,
page & 0xff, // index in lookup table
sa7 & 0x7f, // slave address (7 bit)
rah & 0xff, // High byte of the i2c register address
nbwr & 0xf, // Number of bytes to write (1..10)
dly & 0xff); // Bit delay - number of mclk periods in 1/4 of the SCL period
return count;
}
static ssize_t set_i2c_tbl_rd_human(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
int chn = get_channel_from_name(attr) ;
int ni, page, two_byte_addr, num_bytes,bit_delay;
ni = sscanf(buf, "%i %i %i %i %i", &page, &two_byte_addr, &num_bytes, &bit_delay);
if (ni < 2)
dev_err(dev, "Requires 4 parameters: page, two byte addr (0 - 8bit,1 - 16 bit reg. addr), number of bytes to read, bytes to write (1..10), 1/4 scl period in mclk\n");
return -EINVAL;
set_sensor_i2c_rd( chn,
page & 0xff, // index in lookup table
two_byte_addr & 1, // Number of address bytes (0 - one byte, 1 - two bytes)
num_bytes & 7, // Number of bytes to read (1..8, 0 means 8)
bit_delay & 0xff); // Bit delay - number of mclk periods in 1/4 of the SCL period
return count;
}
static ssize_t set_i2c_read(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
int chn = get_channel_from_name(attr) ;
int ni, page, sa7, addr;
ni = sscanf(buf, "%i %i %i", &page, &sa7, addr);
if (ni <3)
dev_err(dev, "Requires 3 parameters: page, sa7, reg_addr\n");
return -EINVAL;
page &= 0xff;
read_sensor_i2c (chn,
page & 0xff, // page (8 bits)
sa7 & 0x7f, // 7-bit i2c slave address
addr & 0xffff); // 8/16 bit address return count;
}
// Get i2c read data from fifo
static ssize_t get_i2c_read(struct device *dev, struct device_attribute *attr, char *buf)
{
int chn = get_channel_from_name(attr) ;
int page = sysfs_page[chn]; // currently selected page for sysfs reads
if (page < 0)
return -ENXIO; /* No such device or address */
return sprintf(buf,"%d\n",read_sensor_i2c_fifo(chn)); // <0 - not ready, 0..255 - data
}
// Get i2c read data from fifo
static ssize_t get_i2c_help(struct device *dev, struct device_attribute *attr, char *buf)
{
return sprintf(buf,"Numeric suffix in file names selects sensor port\n"
"alloc*: read - allocate and return page, write <page> (any data) - free page\n"
"rd_page*: read/write page number used in read operations (-1 if none)\n"
"tbl_raw*: read - raw hex table value (for current rd_page), write <page> <data32> set page\n"
"tbl_wr*: read - decoded table entry for current rd_page, write <page> <sa7> <high_addr_byte> <bytes_to_write> <dly>\n"
"tbl_rd*: read - decoded table entry for current rd_page, write <page> <2-byte addr> <bytes_to_read> <dly>\n"
"tbl_rd* and tbl_wr* return same result when read. Delay is 8 bit, 250 - 200KHz SCL\n");
}
// Sysfs top
/* alloc*: read - allocate and return page, write (any data) - free page */
static DEVICE_ATTR(alloc0 , SYSFS_PERMISSIONS , get_i2c_page_alloc , free_i2c_page);
static DEVICE_ATTR(alloc1 , SYSFS_PERMISSIONS , get_i2c_page_alloc , free_i2c_page);
static DEVICE_ATTR(alloc2 , SYSFS_PERMISSIONS , get_i2c_page_alloc , free_i2c_page);
static DEVICE_ATTR(alloc3 , SYSFS_PERMISSIONS , get_i2c_page_alloc , free_i2c_page);
/* rd_page*: read/write page number used in read operations */
static DEVICE_ATTR(rd_page0 , SYSFS_PERMISSIONS , get_i2c_page_inuse, set_i2c_page_inuse);
static DEVICE_ATTR(rd_page1 , SYSFS_PERMISSIONS , get_i2c_page_inuse, set_i2c_page_inuse);
static DEVICE_ATTR(rd_page2 , SYSFS_PERMISSIONS , get_i2c_page_inuse, set_i2c_page_inuse);
static DEVICE_ATTR(rd_page3 , SYSFS_PERMISSIONS , get_i2c_page_inuse, set_i2c_page_inuse);
static DEVICE_ATTR(tbl_raw0 , SYSFS_PERMISSIONS , get_i2c_tbl_raw, set_i2c_tbl_raw);
static DEVICE_ATTR(tbl_raw1 , SYSFS_PERMISSIONS , get_i2c_tbl_raw, set_i2c_tbl_raw);
static DEVICE_ATTR(tbl_raw2 , SYSFS_PERMISSIONS , get_i2c_tbl_raw, set_i2c_tbl_raw);
static DEVICE_ATTR(tbl_raw3 , SYSFS_PERMISSIONS , get_i2c_tbl_raw, set_i2c_tbl_raw);
static DEVICE_ATTR(tbl_wr0 , SYSFS_PERMISSIONS , get_i2c_tbl_human, set_i2c_tbl_wr_human);
static DEVICE_ATTR(tbl_wr1 , SYSFS_PERMISSIONS , get_i2c_tbl_human, set_i2c_tbl_wr_human);
static DEVICE_ATTR(tbl_wr2 , SYSFS_PERMISSIONS , get_i2c_tbl_human, set_i2c_tbl_wr_human);
static DEVICE_ATTR(tbl_wr3 , SYSFS_PERMISSIONS , get_i2c_tbl_human, set_i2c_tbl_wr_human);
static DEVICE_ATTR(tbl_rd0 , SYSFS_PERMISSIONS , get_i2c_tbl_human, set_i2c_tbl_rd_human);
static DEVICE_ATTR(tbl_rd1 , SYSFS_PERMISSIONS , get_i2c_tbl_human, set_i2c_tbl_rd_human);
static DEVICE_ATTR(tbl_rd2 , SYSFS_PERMISSIONS , get_i2c_tbl_human, set_i2c_tbl_rd_human);
static DEVICE_ATTR(tbl_rd3 , SYSFS_PERMISSIONS , get_i2c_tbl_human, set_i2c_tbl_rd_human);
static DEVICE_ATTR(i2c_rd0 , SYSFS_PERMISSIONS , get_i2c_read, set_i2c_read);
static DEVICE_ATTR(i2c_rd1 , SYSFS_PERMISSIONS , get_i2c_read, set_i2c_read);
static DEVICE_ATTR(i2c_rd2 , SYSFS_PERMISSIONS , get_i2c_read, set_i2c_read);
static DEVICE_ATTR(i2c_rd3 , SYSFS_PERMISSIONS , get_i2c_read, set_i2c_read);
static DEVICE_ATTR(help, SYSFS_PERMISSIONS & SYSFS_READONLY, get_i2c_help, NULL);
static struct attribute *root_dev_attrs[] = {
&dev_attr_alloc0.attr,
&dev_attr_alloc1.attr,
&dev_attr_alloc2.attr,
&dev_attr_alloc3.attr,
&dev_attr_rd_page0.attr,
&dev_attr_rd_page1.attr,
&dev_attr_rd_page2.attr,
&dev_attr_rd_page3.attr,
&dev_attr_tbl_raw0.attr,
&dev_attr_tbl_raw1.attr,
&dev_attr_tbl_raw2.attr,
&dev_attr_tbl_raw3.attr,
&dev_attr_tbl_wr0.attr,
&dev_attr_tbl_wr1.attr,
&dev_attr_tbl_wr2.attr,
&dev_attr_tbl_wr3.attr,
&dev_attr_tbl_rd0.attr,
&dev_attr_tbl_rd1.attr,
&dev_attr_tbl_rd2.attr,
&dev_attr_tbl_rd3.attr,
&dev_attr_i2c_rd0.attr,
&dev_attr_i2c_rd1.attr,
&dev_attr_i2c_rd2.attr,
&dev_attr_i2c_rd3.attr,
&dev_attr_help.attr,
NULL
};
static const struct attribute_group dev_attr_root_group = {
.attrs = root_dev_attrs,
.name = NULL,
};
static int elphel393_sens_i2c_sysfs_register(struct platform_device *pdev)
{
int retval=0;
struct device *dev = &pdev->dev;
if (&dev->kobj) {
if (((retval = sysfs_create_group(&dev->kobj, &dev_attr_root_group)))<0) return retval;
}
return retval;
}
// =======================================
static void elphel393_sensor_i2c_init_of(struct platform_device *pdev)
{
const __be32 * config_data;
const char * config_string;
char str[40];
int len,chn,pre_disabled,old_dis_por,rc,chn_bits;
struct device_node *node = pdev->dev.of_node;
// struct elphel393_pwr_data_t *clientdata = platform_get_drvdata(pdev);
// struct i2c_client *ltc3589_client= to_i2c_client(clientdata->ltc3489_dev);
if (node) {
/*TODO: Configure some i2c devices here (slaves, formats, speeds) to be used by names*/
}
dev_info(&pdev->dev,"elphel393_sensor_i2c configuration done\n");
}
static int elphel393_sensor_i2c_probe(struct platform_device *pdev)
{
/*
struct gpio_chip *chip;
// struct device * ltc3489_dev;
int i,rc;
int base[2];
struct i2c_client *ltc3589_client;
struct elphel393_pwr_data_t *clientdata = NULL;
*/
pr_info("Probing elphel393-sensor-i2c\n");
elphel393_sens_i2c_sysfs_register(pdev);
i2c_page_alloc_init();
#if 0
clientdata = devm_kzalloc(&pdev->dev, sizeof(*clientdata), GFP_KERNEL);
#endif
elphel393_sensor_i2c_init_of(pdev);
pr_info("done probing elphel393-sensor-i2c\n");
return 0;
}
static int elphel393_sensor_i2c_remove(struct platform_device *pdev)
{
dev_info(&pdev->dev,"Removing elphel393-sensor-i2c");
return 0;
}
static struct of_device_id elphel393_sensor_i2c_of_match[] = {
{ .compatible = "elphel,elphel393-sensor-i2c-1.00", },
{ /* end of table */}
};
MODULE_DEVICE_TABLE(of, elphel393_sensor_i2c_of_match);
static struct platform_driver elphel393_sensor_i2c = {
.probe = elphel393_sensor_i2c_probe,
.remove = elphel393_sensor_i2c_remove,
.driver = {
.name = "elphel393-sensor-i2c",
.owner = THIS_MODULE,
.of_match_table = elphel393_sensor_i2c_of_match,
.pm = NULL, /* power management */
},
};
module_platform_driver(elphel393_sensor_i2c);
MODULE_AUTHOR("Andrey Filippov <andrey@elphel.com>");
MODULE_DESCRIPTION("Elphel 10393 sensor ports i2c");
MODULE_LICENSE("GPL");
/*******************************************************************************
* FILE NAME : sensor_i2c.h
* DESCRIPTION: Interface to FPGA-based i2c sequencer for sensor ports
* Copyright 2016 (C) Elphel, Inc.
* -----------------------------------------------------------------------------*
*
* 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/>.
*******************************************************************************/
// I2C device description to be used with i2c sequencer
/*
typedef struct x393_i2c_device_tag{
char * name;
u8 slave7; // slave address (7-bit)
u8 address_bytes;
u8 data_bytes;
int scl_khz; // maximal SCL frequency in KHz (currently limited by 200KHz slowest)
struct x393_i2c_device_tag * next;
} x393_i2c_device_t;
*/
/* Reserve i2c page (1 of 256 for a sensor port)*/
int i2c_page_alloc(int chn);
/* Free i2c page */
void i2c_page_free(int chn, int page);
/* Set i2c table entry to raw data (will just overwrite tbl_mode = 2) */
void set_sensor_i2c_raw(int chn,
int page, // index in lookup table
u32 data); // Bit delay - number of mclk periods in 1/4 of the SCL period
/* Set i2c table entry for write operation */
void set_sensor_i2c_wr(int chn,
int page, // index in lookup table
int sa, // slave address (7 bit)
int rah, // High byte of the i2c register address
int num_bytes, //Number of bytes to write (1..10)
int bit_delay); // Bit delay - number of mclk periods in 1/4 of the SCL period
/* Set i2c table entry for read operation */
void set_sensor_i2c_rd(int chn,
int page, // index in lookup table
int two_byte_addr, // Number of address bytes (0 - one byte, 1 - two bytes)
int num_bytes, // Number of bytes to read (1..8, 0 means 8)
int bit_delay);// Bit delay - number of mclk periods in 1/4 of the SCL period
/*
// Write i2c command to the i2c command sequencer
// 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
*/
/* Write one or multiple DWORDs to i2c relative (modulo16) address. Use offs = 0 for immediate (ASAP) command */
/* Length of data is determined by the page data already preset */
int write_sensor_i2c_rel (int chn,
int offs, // 4 bits
u32 * data);
/* Same to absolute (modulo16) address */
int write_sensor_i2c_abs (int chn,
int offs, // 4 bits
u32 * data);
/* Write sensor 16 bit (or 8 bit as programmed in the table) data in immediate mode */
void write_sensor_reg16 (int chn,
int page, // page (8 bits)
int addr, // low 8 bits
u32 data); // 16 or 8-bit data (LSB aligned)
/* Initiate sensor i2c read in immediate mode (data itself has to be read from FIFO with read_sensor_i2c_fifo)*/
void read_sensor_i2c (int chn,
int page, // page (8 bits)
int sa7, // 7-bit i2c slave address
int addr); // 8/16 bit address
/* Read next byte from the channel i2c FIFO. Return byte or -1 if no data available */
/* Sensor channel status should be in auto update mode (3) */
int read_sensor_i2c_fifo(int chn);
/*******************************************************************************
* File: x393.c
* Date: 2016-04-06
* Author: auto-generated file, see x393_export_c.py
* Description: Functions definitions to access x393 hardware registers
*******************************************************************************/
#include <linux/io.h>
#include "x393.h"
static void __iomem* mmio_ptr;
// init_mmio_ptr() should be called once before using any of the other defined functions
int init_mmio_ptr(void) {mmio_ptr = ioremap(0x40000000, 0x00003000); if (!mmio_ptr) return -1; else return 0;}
// R/W addresses to set up memory arbiter priorities. For sensors (chn = 8..11), for compressors - 12..15
void set_x393_mcntrl_arbiter_priority (x393_arbite_pri_t d, int chn){writel(d.d32, mmio_ptr + (0x0180 + 0x4 * chn));} // Set memory arbiter priority (currently r/w, may become just wo)
x393_arbite_pri_t get_x393_mcntrl_arbiter_priority (int chn) { x393_arbite_pri_t d; d.d32 = readl(mmio_ptr + (0x0180 + 0x4 * chn)); return d; }
// Enable/disable memory channels (bits in a 16-bit word). For sensors (chn = 8..11), for compressors - 12..15
void set_x393_mcntrl_chn_en (x393_mcntr_chn_en_t d){writel(d.d32, mmio_ptr + 0x01c0);} // Enable/disable memory channels (currently r/w, may become just wo)
x393_mcntr_chn_en_t get_x393_mcntrl_chn_en (void) { x393_mcntr_chn_en_t d; d.d32 = readl(mmio_ptr + 0x01c0); return d; }
void set_x393_mcntrl_dqs_dqm_patt (x393_mcntr_dqs_dqm_patt_t d){writel(d.d32, mmio_ptr + 0x0140);} // Setup DQS and DQM patterns
x393_mcntr_dqs_dqm_patt_t get_x393_mcntrl_dqs_dqm_patt (void) { x393_mcntr_dqs_dqm_patt_t d; d.d32 = readl(mmio_ptr + 0x0140); return d; }
void set_x393_mcntrl_dq_dqs_tri (x393_mcntr_dqs_dqm_tri_t d){writel(d.d32, mmio_ptr + 0x0144);} // Setup DQS and DQ on/off sequence
x393_mcntr_dqs_dqm_tri_t get_x393_mcntrl_dq_dqs_tri (void) { x393_mcntr_dqs_dqm_tri_t d; d.d32 = readl(mmio_ptr + 0x0144); return d; }
// Following enable/disable addresses can be written with any data, only addresses matter
void x393_mcntrl_dis (void) {writel(0, mmio_ptr + 0x00c0);} // Disable DDR3 memory controller
void x393_mcntrl_en (void) {writel(0, mmio_ptr + 0x00c4);} // Enable DDR3 memory controller
void x393_mcntrl_refresh_dis (void) {writel(0, mmio_ptr + 0x00c8);} // Disable DDR3 memory refresh
void x393_mcntrl_refresh_en (void) {writel(0, mmio_ptr + 0x00cc);} // Enable DDR3 memory refresh
void x393_mcntrl_sdrst_dis (void) {writel(0, mmio_ptr + 0x0098);} // Disable DDR3 memory reset
void x393_mcntrl_sdrst_en (void) {writel(0, mmio_ptr + 0x009c);} // Enable DDR3 memory reset
void x393_mcntrl_cke_dis (void) {writel(0, mmio_ptr + 0x00a0);} // Disable DDR3 memory CKE
void x393_mcntrl_cke_en (void) {writel(0, mmio_ptr + 0x00a4);} // Enable DDR3 memory CKE
void x393_mcntrl_cmda_dis (void) {writel(0, mmio_ptr + 0x0090);} // Disable DDR3 memory command/address lines
void x393_mcntrl_cmda_en (void) {writel(0, mmio_ptr + 0x0094);} // Enable DDR3 memory command/address lines
// Set DDR3 memory controller I/O delays and other timing parameters (should use individually calibrated values)
void set_x393_mcntrl_dq_odly0 (x393_dly_t d, int chn){writel(d.d32, mmio_ptr + (0x0200 + 0x4 * chn));} // Lane0 DQ output delays
x393_dly_t get_x393_mcntrl_dq_odly0 (int chn) { x393_dly_t d; d.d32 = readl(mmio_ptr + (0x0200 + 0x4 * chn)); return d; }
void set_x393_mcntrl_dq_odly1 (x393_dly_t d, int chn){writel(d.d32, mmio_ptr + (0x0280 + 0x4 * chn));} // Lane1 DQ output delays
x393_dly_t get_x393_mcntrl_dq_odly1 (int chn) { x393_dly_t d; d.d32 = readl(mmio_ptr + (0x0280 + 0x4 * chn)); return d; }
void set_x393_mcntrl_dq_idly0 (x393_dly_t d, int chn){writel(d.d32, mmio_ptr + (0x0240 + 0x4 * chn));} // Lane0 DQ input delays
x393_dly_t get_x393_mcntrl_dq_idly0 (int chn) { x393_dly_t d; d.d32 = readl(mmio_ptr + (0x0240 + 0x4 * chn)); return d; }
void set_x393_mcntrl_dq_idly1 (x393_dly_t d, int chn){writel(d.d32, mmio_ptr + (0x02c0 + 0x4 * chn));} // Lane1 DQ input delays
x393_dly_t get_x393_mcntrl_dq_idly1 (int chn) { x393_dly_t d; d.d32 = readl(mmio_ptr + (0x02c0 + 0x4 * chn)); return d; }
void set_x393_mcntrl_dqs_odly0 (x393_dly_t d) {writel(d.d32, mmio_ptr + 0x0220);} // Lane0 DQS output delay
x393_dly_t get_x393_mcntrl_dqs_odly0 (void) { x393_dly_t d; d.d32 = readl(mmio_ptr + 0x0220); return d; }
void set_x393_mcntrl_dqs_odly1 (x393_dly_t d) {writel(d.d32, mmio_ptr + 0x02a0);} // Lane1 DQS output delay
x393_dly_t get_x393_mcntrl_dqs_odly1 (void) { x393_dly_t d; d.d32 = readl(mmio_ptr + 0x02a0); return d; }
void set_x393_mcntrl_dqs_idly0 (x393_dly_t d) {writel(d.d32, mmio_ptr + 0x0260);} // Lane0 DQS input delay
x393_dly_t get_x393_mcntrl_dqs_idly0 (void) { x393_dly_t d; d.d32 = readl(mmio_ptr + 0x0260); return d; }
void set_x393_mcntrl_dqs_idly1 (x393_dly_t d) {writel(d.d32, mmio_ptr + 0x02e0);} // Lane1 DQS input delay
x393_dly_t get_x393_mcntrl_dqs_idly1 (void) { x393_dly_t d; d.d32 = readl(mmio_ptr + 0x02e0); return d; }
void set_x393_mcntrl_dm_odly0 (x393_dly_t d) {writel(d.d32, mmio_ptr + 0x0224);} // Lane0 DM output delay
x393_dly_t get_x393_mcntrl_dm_odly0 (void) { x393_dly_t d; d.d32 = readl(mmio_ptr + 0x0224); return d; }
void set_x393_mcntrl_dm_odly1 (x393_dly_t d) {writel(d.d32, mmio_ptr + 0x02a4);} // Lane1 DM output delay
x393_dly_t get_x393_mcntrl_dm_odly1 (void) { x393_dly_t d; d.d32 = readl(mmio_ptr + 0x02a4); return d; }
void set_x393_mcntrl_cmda_odly (x393_dly_t d, int chn){writel(d.d32, mmio_ptr + (0x0300 + 0x4 * chn));} // Address, bank and commands delays
x393_dly_t get_x393_mcntrl_cmda_odly (int chn) { x393_dly_t d; d.d32 = readl(mmio_ptr + (0x0300 + 0x4 * chn)); return d; }
void set_x393_mcntrl_phase (x393_dly_t d) {writel(d.d32, mmio_ptr + 0x0380);} // Clock phase
x393_dly_t get_x393_mcntrl_phase (void) { x393_dly_t d; d.d32 = readl(mmio_ptr + 0x0380); return d; }
void x393_mcntrl_dly_set (void) {writel(0, mmio_ptr + 0x0080);} // Set all pre-programmed delays
void set_x393_mcntrl_wbuf_dly (x393_wbuf_dly_t d) {writel(d.d32, mmio_ptr + 0x0148);} // Set write buffer delay
x393_wbuf_dly_t get_x393_mcntrl_wbuf_dly (void) { x393_wbuf_dly_t d; d.d32 = readl(mmio_ptr + 0x0148); return d; }
// Write-only addresses to program memory channels for sensors (chn = 0..3), memory channels 8..11
void x393_sens_mcntrl_scanline_mode (x393_mcntrl_mode_scan_t d, int chn){writel(d.d32, mmio_ptr + (0x1a00 + 0x40 * chn));} // Set mode register (write last after other channel registers are set)
void set_x393_sens_mcntrl_scanline_status_cntrl(x393_status_ctrl_t d, int chn){writel(d.d32, mmio_ptr + (0x1a04 + 0x40 * chn));} // Set status control register (status update mode)
x393_status_ctrl_t get_x393_sens_mcntrl_scanline_status_cntrl(int chn) { x393_status_ctrl_t d; d.d32 = readl(mmio_ptr + (0x1a04 + 0x40 * chn)); return d; }
void x393_sens_mcntrl_scanline_startaddr (x393_mcntrl_window_frame_sa_t d, int chn){writel(d.d32, mmio_ptr + (0x1a08 + 0x40 * chn));} // Set frame start address
void x393_sens_mcntrl_scanline_frame_size(x393_mcntrl_window_frame_sa_inc_t d, int chn){writel(d.d32, mmio_ptr + (0x1a0c + 0x40 * chn));} // Set frame size (address increment)
void x393_sens_mcntrl_scanline_frame_last(x393_mcntrl_window_last_frame_num_t d, int chn){writel(d.d32, mmio_ptr + (0x1a10 + 0x40 * chn));} // Set last frame number (number of frames in buffer minus 1)
void x393_sens_mcntrl_scanline_frame_full_width(x393_mcntrl_window_full_width_t d, int chn){writel(d.d32, mmio_ptr + (0x1a14 + 0x40 * chn));} // Set frame full(padded) width
void x393_sens_mcntrl_scanline_window_wh (x393_mcntrl_window_width_height_t d, int chn){writel(d.d32, mmio_ptr + (0x1a18 + 0x40 * chn));} // Set frame window size
void x393_sens_mcntrl_scanline_window_x0y0(x393_mcntrl_window_left_top_t d, int chn){writel(d.d32, mmio_ptr + (0x1a1c + 0x40 * chn));} // Set frame position
void x393_sens_mcntrl_scanline_startxy (x393_mcntrl_window_startx_starty_t d, int chn){writel(d.d32, mmio_ptr + (0x1a20 + 0x40 * chn));} // Set startXY register
// Write-only addresses to program memory channels for compressors (chn = 0..3), memory channels 12..15
void x393_sens_mcntrl_tiled_mode (x393_mcntrl_mode_scan_t d, int chn){writel(d.d32, mmio_ptr + (0x1b00 + 0x40 * chn));} // Set mode register (write last after other channel registers are set)
void set_x393_sens_mcntrl_tiled_status_cntrl(x393_status_ctrl_t d, int chn){writel(d.d32, mmio_ptr + (0x1b04 + 0x40 * chn));} // Set status control register (status update mode)
x393_status_ctrl_t get_x393_sens_mcntrl_tiled_status_cntrl(int chn) { x393_status_ctrl_t d; d.d32 = readl(mmio_ptr + (0x1b04 + 0x40 * chn)); return d; }
void x393_sens_mcntrl_tiled_startaddr (x393_mcntrl_window_frame_sa_t d, int chn){writel(d.d32, mmio_ptr + (0x1b08 + 0x40 * chn));} // Set frame start address
void x393_sens_mcntrl_tiled_frame_size (x393_mcntrl_window_frame_sa_inc_t d, int chn){writel(d.d32, mmio_ptr + (0x1b0c + 0x40 * chn));} // Set frame size (address increment)
void x393_sens_mcntrl_tiled_frame_last (x393_mcntrl_window_last_frame_num_t d, int chn){writel(d.d32, mmio_ptr + (0x1b10 + 0x40 * chn));} // Set last frame number (number of frames in buffer minus 1)
void x393_sens_mcntrl_tiled_frame_full_width(x393_mcntrl_window_full_width_t d, int chn){writel(d.d32, mmio_ptr + (0x1b14 + 0x40 * chn));} // Set frame full(padded) width
void x393_sens_mcntrl_tiled_window_wh (x393_mcntrl_window_width_height_t d, int chn){writel(d.d32, mmio_ptr + (0x1b18 + 0x40 * chn));} // Set frame window size
void x393_sens_mcntrl_tiled_window_x0y0 (x393_mcntrl_window_left_top_t d, int chn){writel(d.d32, mmio_ptr + (0x1b1c + 0x40 * chn));} // Set frame position
void x393_sens_mcntrl_tiled_startxy (x393_mcntrl_window_startx_starty_t d, int chn){writel(d.d32, mmio_ptr + (0x1b20 + 0x40 * chn));} // Set startXY register
void x393_sens_mcntrl_tiled_tile_whs (x393_mcntrl_window_tile_whs_t d, int chn){writel(d.d32, mmio_ptr + (0x1b24 + 0x40 * chn));} // Set tile size/step (tiled mode only)
// Write-only addresses to program memory channel for membridge, memory channel 1
void x393_membridge_scanline_mode (x393_mcntrl_mode_scan_t d){writel(d.d32, mmio_ptr + 0x0480);} // Set mode register (write last after other channel registers are set)
void set_x393_membridge_scanline_status_cntrl(x393_status_ctrl_t d){writel(d.d32, mmio_ptr + 0x0484);} // Set status control register (status update mode)
x393_status_ctrl_t get_x393_membridge_scanline_status_cntrl(void) { x393_status_ctrl_t d; d.d32 = readl(mmio_ptr + 0x0484); return d; }
void x393_membridge_scanline_startaddr (x393_mcntrl_window_frame_sa_t d){writel(d.d32, mmio_ptr + 0x0488);} // Set frame start address
void x393_membridge_scanline_frame_size (x393_mcntrl_window_frame_sa_inc_t d){writel(d.d32, mmio_ptr + 0x048c);} // Set frame size (address increment)
void x393_membridge_scanline_frame_last (x393_mcntrl_window_last_frame_num_t d){writel(d.d32, mmio_ptr + 0x0490);} // Set last frame number (number of frames in buffer minus 1)
void x393_membridge_scanline_frame_full_width(x393_mcntrl_window_full_width_t d){writel(d.d32, mmio_ptr + 0x0494);} // Set frame full(padded) width
void x393_membridge_scanline_window_wh (x393_mcntrl_window_width_height_t d){writel(d.d32, mmio_ptr + 0x0498);} // Set frame window size
void x393_membridge_scanline_window_x0y0 (x393_mcntrl_window_left_top_t d){writel(d.d32, mmio_ptr + 0x049c);} // Set frame position
void x393_membridge_scanline_startxy (x393_mcntrl_window_startx_starty_t d){writel(d.d32, mmio_ptr + 0x04a0);} // Set startXY register
void x393_membridge_ctrl (x393_membridge_cmd_t d){writel(d.d32, mmio_ptr + 0x0800);} // Issue membridge command
void set_x393_membridge_status_cntrl (x393_status_ctrl_t d){writel(d.d32, mmio_ptr + 0x0804);} // Set membridge status control register
x393_status_ctrl_t get_x393_membridge_status_cntrl (void) { x393_status_ctrl_t d; d.d32 = readl(mmio_ptr + 0x0804); return d; }
void x393_membridge_lo_addr64 (u29_t d) {writel(d.d32, mmio_ptr + 0x0808);} // start address of the system memory range in QWORDs (4 LSBs==0)
void x393_membridge_size64 (u29_t d) {writel(d.d32, mmio_ptr + 0x080c);} // size of the system memory range in QWORDs (4 LSBs==0), rolls over
void x393_membridge_start64 (u29_t d) {writel(d.d32, mmio_ptr + 0x0810);} // start of transfer offset to system memory range in QWORDs (4 LSBs==0)
void x393_membridge_len64 (u29_t d) {writel(d.d32, mmio_ptr + 0x0814);} // Full length of transfer in QWORDs
void x393_membridge_width64 (u29_t d) {writel(d.d32, mmio_ptr + 0x0818);} // Frame width in QWORDs (last xfer in each line may be partial)
void x393_membridge_mode (x393_membridge_mode_t d){writel(d.d32, mmio_ptr + 0x081c);} // AXI cache mode
// Write-only addresses to PS PIO (Software generated DDR3 memory access sequences)
void x393_mcntrl_ps_en_rst (x393_ps_pio_en_rst_t d){writel(d.d32, mmio_ptr + 0x0400);} // Set PS PIO enable and reset
void x393_mcntrl_ps_cmd (x393_ps_pio_cmd_t d){writel(d.d32, mmio_ptr + 0x0404);} // Set PS PIO commands
void set_x393_mcntrl_ps_status_cntrl (x393_status_ctrl_t d){writel(d.d32, mmio_ptr + 0x0408);} // Set PS PIO status control register (status update mode)
x393_status_ctrl_t get_x393_mcntrl_ps_status_cntrl (void) { x393_status_ctrl_t d; d.d32 = readl(mmio_ptr + 0x0408); return d; }
// Write-only addresses to to program status report mode for memory controller
void set_x393_mcontr_phy_status_cntrl (x393_status_ctrl_t d){writel(d.d32, mmio_ptr + 0x0150);} // Set status control register (status update mode)
x393_status_ctrl_t get_x393_mcontr_phy_status_cntrl (void) { x393_status_ctrl_t d; d.d32 = readl(mmio_ptr + 0x0150); return d; }
void set_x393_mcontr_top_16bit_status_cntrl(x393_status_ctrl_t d){writel(d.d32, mmio_ptr + 0x014c);} // Set status control register (status update mode)
x393_status_ctrl_t get_x393_mcontr_top_16bit_status_cntrl(void) { x393_status_ctrl_t d; d.d32 = readl(mmio_ptr + 0x014c); return d; }
// Write-only addresses to to program status report mode for test channels
void set_x393_mcntrl_test01_chn2_status_cntrl(x393_status_ctrl_t d){writel(d.d32, mmio_ptr + 0x03d4);} // Set status control register (status update mode)
x393_status_ctrl_t get_x393_mcntrl_test01_chn2_status_cntrl(void) { x393_status_ctrl_t d; d.d32 = readl(mmio_ptr + 0x03d4); return d; }
void set_x393_mcntrl_test01_chn3_status_cntrl(x393_status_ctrl_t d){writel(d.d32, mmio_ptr + 0x03dc);} // Set status control register (status update mode)
x393_status_ctrl_t get_x393_mcntrl_test01_chn3_status_cntrl(void) { x393_status_ctrl_t d; d.d32 = readl(mmio_ptr + 0x03dc); return d; }
void set_x393_mcntrl_test01_chn4_status_cntrl(x393_status_ctrl_t d){writel(d.d32, mmio_ptr + 0x03e4);} // Set status control register (status update mode)
x393_status_ctrl_t get_x393_mcntrl_test01_chn4_status_cntrl(void) { x393_status_ctrl_t d; d.d32 = readl(mmio_ptr + 0x03e4); return d; }
// Write-only addresses for test channels commands
void x393_mcntrl_test01_chn2_mode (x393_test01_mode_t d){writel(d.d32, mmio_ptr + 0x03d0);} // Set command for test01 channel 2
void x393_mcntrl_test01_chn3_mode (x393_test01_mode_t d){writel(d.d32, mmio_ptr + 0x03d8);} // Set command for test01 channel 3
void x393_mcntrl_test01_chn4_mode (x393_test01_mode_t d){writel(d.d32, mmio_ptr + 0x03e0);} // Set command for test01 channel 4
// Read-only addresses for status information
x393_status_mcntrl_phy_t x393_mcontr_phy_status (void) { x393_status_mcntrl_phy_t d; d.d32 = readl(mmio_ptr + 0x2000); return d; } // Status register for MCNTRL PHY
x393_status_mcntrl_top_t x393_mcontr_top_status (void) { x393_status_mcntrl_top_t d; d.d32 = readl(mmio_ptr + 0x2004); return d; } // Status register for MCNTRL requests
x393_status_mcntrl_ps_t x393_mcntrl_ps_status (void) { x393_status_mcntrl_ps_t d; d.d32 = readl(mmio_ptr + 0x2008); return d; } // Status register for MCNTRL software R/W
x393_status_mcntrl_lintile_t x393_mcntrl_chn1_status (void) { x393_status_mcntrl_lintile_t d; d.d32 = readl(mmio_ptr + 0x2010); return d; } // Status register for MCNTRL CHN1 (membridge)
x393_status_mcntrl_lintile_t x393_mcntrl_chn3_status (void) { x393_status_mcntrl_lintile_t d; d.d32 = readl(mmio_ptr + 0x2018); return d; } // Status register for MCNTRL CHN3 (scanline)
x393_status_mcntrl_lintile_t x393_mcntrl_chn2_status (void) { x393_status_mcntrl_lintile_t d; d.d32 = readl(mmio_ptr + 0x2014); return d; } // Status register for MCNTRL CHN2 (tiled)
x393_status_mcntrl_lintile_t x393_mcntrl_chn4_status (void) { x393_status_mcntrl_lintile_t d; d.d32 = readl(mmio_ptr + 0x201c); return d; } // Status register for MCNTRL CHN4 (tiled)
x393_status_mcntrl_testchn_t x393_test01_chn2_status (void) { x393_status_mcntrl_testchn_t d; d.d32 = readl(mmio_ptr + 0x20f4); return d; } // Status register for test channel 2
x393_status_mcntrl_testchn_t x393_test01_chn3_status (void) { x393_status_mcntrl_testchn_t d; d.d32 = readl(mmio_ptr + 0x20f8); return d; } // Status register for test channel 3
x393_status_mcntrl_testchn_t x393_test01_chn4_status (void) { x393_status_mcntrl_testchn_t d; d.d32 = readl(mmio_ptr + 0x20fc); return d; } // Status register for test channel 4
x393_status_membridge_t x393_membridge_status (void) { x393_status_membridge_t d; d.d32 = readl(mmio_ptr + 0x20ec); return d; } // Status register for membridge
// Write-only control of the sensor channels
void x393_sens_mode (x393_sens_mode_t d, int sens_num){writel(d.d32, mmio_ptr + (0x1000 + 0x100 * sens_num));} // Write sensor channel mode
void x393_sensi2c_ctrl (x393_i2c_ctltbl_t d, int sens_num){writel(d.d32, mmio_ptr + (0x1008 + 0x100 * sens_num));} // Control sensor i2c, write i2c LUT
void set_x393_sensi2c_status_ctrl (x393_status_ctrl_t d, int sens_num){writel(d.d32, mmio_ptr + (0x100c + 0x100 * sens_num));} // Setup sensor i2c status report mode
x393_status_ctrl_t get_x393_sensi2c_status_ctrl (int sens_num) { x393_status_ctrl_t d; d.d32 = readl(mmio_ptr + (0x100c + 0x100 * sens_num)); return d; }
void x393_sens_sync_mult (x393_sens_sync_mult_t d, int sens_num){writel(d.d32, mmio_ptr + (0x1018 + 0x100 * sens_num));} // Configure frames combining
void x393_sens_sync_late (x393_sens_sync_late_t d, int sens_num){writel(d.d32, mmio_ptr + (0x101c + 0x100 * sens_num));} // Configure frame sync delay
void x393_sensio_ctrl (x393_sensio_ctl_t d, int sens_num){writel(d.d32, mmio_ptr + (0x1020 + 0x100 * sens_num));} // Configure sensor I/O port
void set_x393_sensio_status_cntrl (x393_status_ctrl_t d, int sens_num){writel(d.d32, mmio_ptr + (0x1024 + 0x100 * sens_num));} // Set status control for SENSIO module
x393_status_ctrl_t get_x393_sensio_status_cntrl (int sens_num) { x393_status_ctrl_t d; d.d32 = readl(mmio_ptr + (0x1024 + 0x100 * sens_num)); return d; }
void x393_sensio_jtag (x393_sensio_jtag_t d, int sens_num){writel(d.d32, mmio_ptr + (0x1028 + 0x100 * sens_num));} // Programming interface for multiplexer FPGA (with X393_SENSIO_STATUS)
void set_x393_sensio_width (x393_sensio_width_t d, int sens_num){writel(d.d32, mmio_ptr + (0x102c + 0x100 * sens_num));} // Set sensor line in pixels (0 - use line sync from the sensor)
x393_sensio_width_t get_x393_sensio_width (int sens_num) { x393_sensio_width_t d; d.d32 = readl(mmio_ptr + (0x102c + 0x100 * sens_num)); return d; }
void set_x393_sensio_tim0 (x393_sensio_tim0_t d, int sens_num){writel(d.d32, mmio_ptr + (0x1030 + 0x100 * sens_num));} // Sensor port i/o timing configuration, register 0
x393_sensio_tim0_t get_x393_sensio_tim0 (int sens_num) { x393_sensio_tim0_t d; d.d32 = readl(mmio_ptr + (0x1030 + 0x100 * sens_num)); return d; }
void set_x393_sensio_tim1 (x393_sensio_tim1_t d, int sens_num){writel(d.d32, mmio_ptr + (0x1034 + 0x100 * sens_num));} // Sensor port i/o timing configuration, register 1
x393_sensio_tim1_t get_x393_sensio_tim1 (int sens_num) { x393_sensio_tim1_t d; d.d32 = readl(mmio_ptr + (0x1034 + 0x100 * sens_num)); return d; }
void set_x393_sensio_tim2 (x393_sensio_tim2_t d, int sens_num){writel(d.d32, mmio_ptr + (0x1038 + 0x100 * sens_num));} // Sensor port i/o timing configuration, register 2
x393_sensio_tim2_t get_x393_sensio_tim2 (int sens_num) { x393_sensio_tim2_t d; d.d32 = readl(mmio_ptr + (0x1038 + 0x100 * sens_num)); return d; }
void set_x393_sensio_tim3 (x393_sensio_tim3_t d, int sens_num){writel(d.d32, mmio_ptr + (0x103c + 0x100 * sens_num));} // Sensor port i/o timing configuration, register 3
x393_sensio_tim3_t get_x393_sensio_tim3 (int sens_num) { x393_sensio_tim3_t d; d.d32 = readl(mmio_ptr + (0x103c + 0x100 * sens_num)); return d; }
// 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
void x393_sensi2c_abs (u32 d, int sens_num, int offset){writel(d, mmio_ptr + (0x1040 + 0x40 * sens_num + 0x1 * offset));} // Write sensor i2c sequencer
void x393_sensi2c_rel (u32 d, int sens_num, int offset){writel(d, mmio_ptr + (0x1080 + 0x40 * sens_num + 0x1 * offset));} // Write sensor i2c sequencer
// Lens vignetting correction (for each sub-frame separately)
void set_x393_lens_height0_m1 (x393_lens_height_m1_t d, int sens_num){writel(d.d32, mmio_ptr + (0x10f0 + 0x100 * sens_num));} // Subframe 0 height minus 1
x393_lens_height_m1_t get_x393_lens_height0_m1 (int sens_num) { x393_lens_height_m1_t d; d.d32 = readl(mmio_ptr + (0x10f0 + 0x100 * sens_num)); return d; }
void set_x393_lens_height1_m1 (x393_lens_height_m1_t d, int sens_num){writel(d.d32, mmio_ptr + (0x10f4 + 0x100 * sens_num));} // Subframe 1 height minus 1
x393_lens_height_m1_t get_x393_lens_height1_m1 (int sens_num) { x393_lens_height_m1_t d; d.d32 = readl(mmio_ptr + (0x10f4 + 0x100 * sens_num)); return d; }
void set_x393_lens_height2_m1 (x393_lens_height_m1_t d, int sens_num){writel(d.d32, mmio_ptr + (0x10f8 + 0x100 * sens_num));} // Subframe 2 height minus 1
x393_lens_height_m1_t get_x393_lens_height2_m1 (int sens_num) { x393_lens_height_m1_t d; d.d32 = readl(mmio_ptr + (0x10f8 + 0x100 * sens_num)); return d; }
void x393_lens_corr_cnh_addr_data (x393_lens_corr_t d, int sens_num){writel(d.d32, mmio_ptr + (0x10fc + 0x100 * sens_num));} // Combined address/data to write lens vignetting correction coefficients
// Lens vignetting coefficient addresses - use with x393_lens_corr_wo_t (X393_LENS_CORR_CNH_ADDR_DATA)
// Sensor gamma conversion control (See Python code for examples of the table data generation)
void set_x393_sens_gamma_ctrl (x393_gamma_ctl_t d, int sens_num){writel(d.d32, mmio_ptr + (0x10e0 + 0x100 * sens_num));} // Gamma module control
x393_gamma_ctl_t get_x393_sens_gamma_ctrl (int sens_num) { x393_gamma_ctl_t d; d.d32 = readl(mmio_ptr + (0x10e0 + 0x100 * sens_num)); return d; }
void x393_sens_gamma_tbl (x393_gamma_tbl_t d, int sens_num){writel(d.d32, mmio_ptr + (0x10e4 + 0x100 * sens_num));} // Write sensor gamma table address/data (with autoincrement)
void set_x393_sens_gamma_height01m1 (x393_gamma_height01m1_t d, int sens_num){writel(d.d32, mmio_ptr + (0x10e8 + 0x100 * sens_num));} // Gamma module subframes 0,1 heights minus 1
x393_gamma_height01m1_t get_x393_sens_gamma_height01m1 (int sens_num) { x393_gamma_height01m1_t d; d.d32 = readl(mmio_ptr + (0x10e8 + 0x100 * sens_num)); return d; }
void set_x393_sens_gamma_height2m1 (x393_gamma_height2m1_t d, int sens_num){writel(d.d32, mmio_ptr + (0x10ec + 0x100 * sens_num));} // Gamma module subframe 2 height minus 1
x393_gamma_height2m1_t get_x393_sens_gamma_height2m1 (int sens_num) { x393_gamma_height2m1_t d; d.d32 = readl(mmio_ptr + (0x10ec + 0x100 * sens_num)); return d; }
// Windows for histogram subchannels
void set_x393_histogram_lt0 (x393_hist_left_top_t d, int sens_num){writel(d.d32, mmio_ptr + (0x10c0 + 0x100 * sens_num));} // Specify histogram 0 left/top
x393_hist_left_top_t get_x393_histogram_lt0 (int sens_num) { x393_hist_left_top_t d; d.d32 = readl(mmio_ptr + (0x10c0 + 0x100 * sens_num)); return d; }
void set_x393_histogram_wh0 (x393_hist_width_height_m1_t d, int sens_num){writel(d.d32, mmio_ptr + (0x10c4 + 0x100 * sens_num));} // Specify histogram 0 width/height
x393_hist_width_height_m1_t get_x393_histogram_wh0 (int sens_num) { x393_hist_width_height_m1_t d; d.d32 = readl(mmio_ptr + (0x10c4 + 0x100 * sens_num)); return d; }
void set_x393_histogram_lt1 (x393_hist_left_top_t d, int sens_num){writel(d.d32, mmio_ptr + (0x10c8 + 0x100 * sens_num));} // Specify histogram 1 left/top
x393_hist_left_top_t get_x393_histogram_lt1 (int sens_num) { x393_hist_left_top_t d; d.d32 = readl(mmio_ptr + (0x10c8 + 0x100 * sens_num)); return d; }
void set_x393_histogram_wh1 (x393_hist_width_height_m1_t d, int sens_num){writel(d.d32, mmio_ptr + (0x10cc + 0x100 * sens_num));} // Specify histogram 1 width/height
x393_hist_width_height_m1_t get_x393_histogram_wh1 (int sens_num) { x393_hist_width_height_m1_t d; d.d32 = readl(mmio_ptr + (0x10cc + 0x100 * sens_num)); return d; }
void set_x393_histogram_lt2 (x393_hist_left_top_t d, int sens_num){writel(d.d32, mmio_ptr + (0x10d0 + 0x100 * sens_num));} // Specify histogram 2 left/top
x393_hist_left_top_t get_x393_histogram_lt2 (int sens_num) { x393_hist_left_top_t d; d.d32 = readl(mmio_ptr + (0x10d0 + 0x100 * sens_num)); return d; }
void set_x393_histogram_wh2 (x393_hist_width_height_m1_t d, int sens_num){writel(d.d32, mmio_ptr + (0x10d4 + 0x100 * sens_num));} // Specify histogram 2 width/height
x393_hist_width_height_m1_t get_x393_histogram_wh2 (int sens_num) { x393_hist_width_height_m1_t d; d.d32 = readl(mmio_ptr + (0x10d4 + 0x100 * sens_num)); return d; }
void set_x393_histogram_lt3 (x393_hist_left_top_t d, int sens_num){writel(d.d32, mmio_ptr + (0x10d8 + 0x100 * sens_num));} // Specify histogram 3 left/top
x393_hist_left_top_t get_x393_histogram_lt3 (int sens_num) { x393_hist_left_top_t d; d.d32 = readl(mmio_ptr + (0x10d8 + 0x100 * sens_num)); return d; }
void set_x393_histogram_wh3 (x393_hist_width_height_m1_t d, int sens_num){writel(d.d32, mmio_ptr + (0x10dc + 0x100 * sens_num));} // Specify histogram 3 width/height
x393_hist_width_height_m1_t get_x393_histogram_wh3 (int sens_num) { x393_hist_width_height_m1_t d; d.d32 = readl(mmio_ptr + (0x10dc + 0x100 * sens_num)); return d; }
// DMA control for the histograms. Subchannel here is 4*sensor_port+ histogram_subchannel
void set_x393_hist_saxi_mode (x393_hist_saxi_mode_t d){writel(d.d32, mmio_ptr + 0x1440);} // Histogram DMA operation mode
x393_hist_saxi_mode_t get_x393_hist_saxi_mode (void) { x393_hist_saxi_mode_t d; d.d32 = readl(mmio_ptr + 0x1440); return d; }
void set_x393_hist_saxi_addr (x393_hist_saxi_addr_t d, int subchannel){writel(d.d32, mmio_ptr + (0x1400 + 0x4 * subchannel));} // Histogram DMA addresses (in 4096 byte pages)
x393_hist_saxi_addr_t get_x393_hist_saxi_addr (int subchannel) { x393_hist_saxi_addr_t d; d.d32 = readl(mmio_ptr + (0x1400 + 0x4 * subchannel)); return d; }
// Read-only addresses for sensors status information
x393_status_sens_i2c_t x393_sensi2c_status (int sens_num) { x393_status_sens_i2c_t d; d.d32 = readl(mmio_ptr + (0x2080 + 0x8 * sens_num)); return d; } // Status of the sensors i2c
x393_status_sens_io_t x393_sensio_status (int sens_num) { x393_status_sens_io_t d; d.d32 = readl(mmio_ptr + (0x2084 + 0x8 * sens_num)); return d; } // Status of the sensor ports I/O pins
// Compressor bitfields values
// Compressor control
void x393_cmprs_control_reg (x393_cmprs_mode_t d, int cmprs_chn){writel(d.d32, mmio_ptr + (0x1800 + 0x40 * cmprs_chn));} // Program compressor channel operation mode
void set_x393_cmprs_status (x393_status_ctrl_t d, int cmprs_chn){writel(d.d32, mmio_ptr + (0x1804 + 0x40 * cmprs_chn));} // Setup compressor status report mode
x393_status_ctrl_t get_x393_cmprs_status (int cmprs_chn) { x393_status_ctrl_t d; d.d32 = readl(mmio_ptr + (0x1804 + 0x40 * cmprs_chn)); return d; }
void set_x393_cmprs_format (x393_cmprs_frame_format_t d, int cmprs_chn){writel(d.d32, mmio_ptr + (0x1808 + 0x40 * cmprs_chn));} // Compressor frame format
x393_cmprs_frame_format_t get_x393_cmprs_format (int cmprs_chn) { x393_cmprs_frame_format_t d; d.d32 = readl(mmio_ptr + (0x1808 + 0x40 * cmprs_chn)); return d; }
void set_x393_cmprs_color_saturation (x393_cmprs_colorsat_t d, int cmprs_chn){writel(d.d32, mmio_ptr + (0x180c + 0x40 * cmprs_chn));} // Compressor color saturation
x393_cmprs_colorsat_t get_x393_cmprs_color_saturation (int cmprs_chn) { x393_cmprs_colorsat_t d; d.d32 = readl(mmio_ptr + (0x180c + 0x40 * cmprs_chn)); return d; }
void set_x393_cmprs_coring_mode (x393_cmprs_coring_mode_t d, int cmprs_chn){writel(d.d32, mmio_ptr + (0x1810 + 0x40 * cmprs_chn));} // Select coring mode
x393_cmprs_coring_mode_t get_x393_cmprs_coring_mode (int cmprs_chn) { x393_cmprs_coring_mode_t d; d.d32 = readl(mmio_ptr + (0x1810 + 0x40 * cmprs_chn)); return d; }
void x393_cmprs_interrupts (x393_cmprs_interrupts_t d, int cmprs_chn){writel(d.d32, mmio_ptr + (0x1814 + 0x40 * cmprs_chn));} // 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
// Compressor tables control
void x393_cmprs_tables_data (u32 d, int cmprs_chn){writel(d, mmio_ptr + (0x1818 + 0x40 * cmprs_chn));} // Compressor tables data
void x393_cmprs_tables_address (x393_cmprs_table_addr_t d, int cmprs_chn){writel(d.d32, mmio_ptr + (0x181c + 0x40 * cmprs_chn));} // Compressor tables type/address
// Compressor channel status)
x393_cmprs_status_t x393_cmprs_status (int chn) { x393_cmprs_status_t d; d.d32 = readl(mmio_ptr + (0x2040 + 0x4 * chn)); return d; } // Status of the compressor channel (incl. interrupt
u32 x393_cmprs_hifreq (int chn) { u32 d; d = readl(mmio_ptr + (0x2050 + 0x4 * chn)); return d; } // Focus helper high-frequency amount
// 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
void x393_afimux0_en (x393_afimux_en_t d){writel(d.d32, mmio_ptr + 0x1900);} // AFI MUX 0 global/port run/pause control
void set_x393_afimux0_rst (x393_afimux_rst_t d){writel(d.d32, mmio_ptr + 0x1904);} // AFI MUX 0 per-port resets
x393_afimux_rst_t get_x393_afimux0_rst (void) { x393_afimux_rst_t d; d.d32 = readl(mmio_ptr + 0x1904); return d; }
void x393_afimux0_report_mode (x393_afimux_report_t d){writel(d.d32, mmio_ptr + 0x1908);} // AFI MUX 0 readout pointer report mode
void set_x393_afimux0_status_control (x393_status_ctrl_t d){writel(d.d32, mmio_ptr + 0x1910);} // AFI MUX 0 status report mode
x393_status_ctrl_t get_x393_afimux0_status_control (void) { x393_status_ctrl_t d; d.d32 = readl(mmio_ptr + 0x1910); return d; }
void set_x393_afimux0_sa (x393_afimux_sa_t d, int afi_port){writel(d.d32, mmio_ptr + (0x1920 + 0x4 * afi_port));} // AFI MUX 0 DMA buffer start address in 32-byte blocks
x393_afimux_sa_t get_x393_afimux0_sa (int afi_port) { x393_afimux_sa_t d; d.d32 = readl(mmio_ptr + (0x1920 + 0x4 * afi_port)); return d; }
void set_x393_afimux0_len (x393_afimux_len_t d, int afi_port){writel(d.d32, mmio_ptr + (0x1930 + 0x4 * afi_port));} // AFI MUX 0 DMA buffer length in 32-byte blocks
x393_afimux_len_t get_x393_afimux0_len (int afi_port) { x393_afimux_len_t d; d.d32 = readl(mmio_ptr + (0x1930 + 0x4 * afi_port)); return d; }
// Same for the second AXI HP channel (not currently used)
void x393_afimux1_en (x393_afimux_en_t d){writel(d.d32, mmio_ptr + 0x1940);} // AFI MUX 1 global/port run/pause control
void set_x393_afimux1_rst (x393_afimux_rst_t d){writel(d.d32, mmio_ptr + 0x1944);} // AFI MUX 1 per-port resets
x393_afimux_rst_t get_x393_afimux1_rst (void) { x393_afimux_rst_t d; d.d32 = readl(mmio_ptr + 0x1944); return d; }
void x393_afimux1_report_mode (x393_afimux_report_t d){writel(d.d32, mmio_ptr + 0x1948);} // AFI MUX 1 readout pointer report mode
void set_x393_afimux1_status_control (x393_status_ctrl_t d){writel(d.d32, mmio_ptr + 0x1950);} // AFI MUX 1 status report mode
x393_status_ctrl_t get_x393_afimux1_status_control (void) { x393_status_ctrl_t d; d.d32 = readl(mmio_ptr + 0x1950); return d; }
void set_x393_afimux1_sa (x393_afimux_sa_t d, int afi_port){writel(d.d32, mmio_ptr + (0x1960 + 0x4 * afi_port));} // AFI MUX 1 DMA buffer start address in 32-byte blocks
x393_afimux_sa_t get_x393_afimux1_sa (int afi_port) { x393_afimux_sa_t d; d.d32 = readl(mmio_ptr + (0x1960 + 0x4 * afi_port)); return d; }
void set_x393_afimux1_len (x393_afimux_len_t d, int afi_port){writel(d.d32, mmio_ptr + (0x1970 + 0x4 * afi_port));} // AFI MUX 1 DMA buffer length in 32-byte blocks
x393_afimux_len_t get_x393_afimux1_len (int afi_port) { x393_afimux_len_t d; d.d32 = readl(mmio_ptr + (0x1970 + 0x4 * afi_port)); return d; }
// Read-only sensors status information (pointer offset and last sequence number)
x393_afimux_status_t x393_afimux0_status (int afi_port) { x393_afimux_status_t d; d.d32 = readl(mmio_ptr + (0x2060 + 0x4 * afi_port)); return d; } // Status of the AFI MUX 0 (including image pointer)
x393_afimux_status_t x393_afimux1_status (int afi_port) { x393_afimux_status_t d; d.d32 = readl(mmio_ptr + (0x2070 + 0x4 * afi_port)); return d; } // Status of the AFI MUX 1 (including image pointer)
//
// 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
void x393_gpio_set_pins (x393_gpio_set_pins_t d){writel(d.d32, mmio_ptr + 0x1c00);} // State of the GPIO pins and seq. number
void set_x393_gpio_status_control (x393_status_ctrl_t d){writel(d.d32, mmio_ptr + 0x1c04);} // GPIO status control mode
x393_status_ctrl_t get_x393_gpio_status_control (void) { x393_status_ctrl_t d; d.d32 = readl(mmio_ptr + 0x1c04); return d; }
// Read-only GPIO pins state
x393_gpio_status_t x393_gpio_status (void) { x393_gpio_status_t d; d.d32 = readl(mmio_ptr + 0x20c0); return d; } // State of the GPIO pins and seq. number
// RTC control
void set_x393_rtc_usec (x393_rtc_usec_t d) {writel(d.d32, mmio_ptr + 0x1c10);} // RTC microseconds
x393_rtc_usec_t get_x393_rtc_usec (void) { x393_rtc_usec_t d; d.d32 = readl(mmio_ptr + 0x1c10); return d; }
void set_x393_rtc_sec_set (x393_rtc_sec_t d) {writel(d.d32, mmio_ptr + 0x1c14);} // RTC seconds and set clock
x393_rtc_sec_t get_x393_rtc_sec_set (void) { x393_rtc_sec_t d; d.d32 = readl(mmio_ptr + 0x1c14); return d; }
void set_x393_rtc_corr (x393_rtc_corr_t d) {writel(d.d32, mmio_ptr + 0x1c18);} // RTC correction (+/- 1/256 full scale)
x393_rtc_corr_t get_x393_rtc_corr (void) { x393_rtc_corr_t d; d.d32 = readl(mmio_ptr + 0x1c18); return d; }
void set_x393_rtc_set_status (x393_status_ctrl_t d){writel(d.d32, mmio_ptr + 0x1c1c);} // RTC status control mode, write makes a snapshot to be read out
x393_status_ctrl_t get_x393_rtc_set_status (void) { x393_status_ctrl_t d; d.d32 = readl(mmio_ptr + 0x1c1c); return d; }
// Read-only RTC state
x393_rtc_status_t x393_rtc_status (void) { x393_rtc_status_t d; d.d32 = readl(mmio_ptr + 0x20c4); return d; } // RTC status reg
x393_rtc_sec_t x393_rtc_status_sec (void) { x393_rtc_sec_t d; d.d32 = readl(mmio_ptr + 0x20c8); return d; } // RTC snapshot seconds
x393_rtc_usec_t x393_rtc_status_usec (void) { x393_rtc_usec_t d; d.d32 = readl(mmio_ptr + 0x20cc); return d; } // RTC snapshot microseconds
// CAMSYNC control
void x393_camsync_mode (x393_camsync_mode_t d){writel(d.d32, mmio_ptr + 0x1c20);} // CAMSYNC mode
void x393_camsync_trig_src (x393_camsync_io_t d){writel(d.d32, mmio_ptr + 0x1c24);} // CAMSYNC trigger source
void x393_camsync_trig_dst (x393_camsync_io_t d){writel(d.d32, mmio_ptr + 0x1c28);} // CAMSYNC trigger destination
// 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
void set_x393_camsync_trig_period (u32 d) {writel(d, mmio_ptr + 0x1c2c);} // CAMSYNC trigger period
u32 get_x393_camsync_trig_period (void) { u32 d; d = readl(mmio_ptr + 0x1c2c); return d; }
void set_x393_camsync_trig_delay (u32 d, int sens_chn){writel(d, mmio_ptr + (0x1c30 + 0x4 * sens_chn));} // CAMSYNC trigger delay
u32 get_x393_camsync_trig_delay (int sens_chn) { u32 d; d = readl(mmio_ptr + (0x1c30 + 0x4 * sens_chn)); return d; }
// Command sequencer control
// Controller is programmed through 32 locations. Each registers but the control require two writes:
// 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
void x393_cmdframeseq_ctrl (x393_cmdframeseq_mode_t d, int sens_chn){writel(d.d32, mmio_ptr + (0x1e7c + 0x80 * sens_chn));} // CMDFRAMESEQ control register
void x393_cmdframeseq_abs (u32 d, int sens_chn, int offset){writel(d, mmio_ptr + (0x1e00 + 0x20 * sens_chn + 0x1 * offset));} // CMDFRAMESEQ absolute frame address/command
void x393_cmdframeseq_rel (u32 d, int sens_chn, int offset){writel(d, mmio_ptr + (0x1e40 + 0x20 * sens_chn + 0x1 * offset));} // CMDFRAMESEQ relative frame address/command
// Command sequencer multiplexer, provides current frame number for each sensor channel and interrupt status/interrupt masks for them.
// Interrupts and interrupt masks are controlled through channel CMDFRAMESEQ module
void set_x393_cmdseqmux_status_ctrl (x393_status_ctrl_t d){writel(d.d32, mmio_ptr + 0x1c08);} // CMDSEQMUX status control mode (status provides current frame numbers)
x393_status_ctrl_t get_x393_cmdseqmux_status_ctrl (void) { x393_status_ctrl_t d; d.d32 = readl(mmio_ptr + 0x1c08); return d; }
x393_cmdseqmux_status_t x393_cmdseqmux_status (void) { x393_cmdseqmux_status_t d; d.d32 = readl(mmio_ptr + 0x20e0); return d; } // CMDSEQMUX status data (frame numbers and interrupts
// Event logger
// Event logger configuration/data is writtent to the module ising two 32-bit register locations : data and address.
// Address consists of 2 parts - 2-bit page (configuration, imu, gps, message) and a 5-bit sub-address autoincremented when writing data.
// Register pages:
// Register configuration addresses (with X393_LOGGER_PAGE_CONF):
void set_x393_logger_status_ctrl (x393_status_ctrl_t d){writel(d.d32, mmio_ptr + 0x1c88);} // Logger status configuration (to report sample number)
x393_status_ctrl_t get_x393_logger_status_ctrl (void) { x393_status_ctrl_t d; d.d32 = readl(mmio_ptr + 0x1c88); return d; }
void x393_logger_data (x393_logger_data_t d){writel(d.d32, mmio_ptr + 0x1c80);} // Logger register write data
void x393_logger_address (x393_logger_address_t d){writel(d.d32, mmio_ptr + 0x1c84);} // Logger register write page/address
x393_logger_status_t x393_logger_status (void) { x393_logger_status_t d; d.d32 = readl(mmio_ptr + 0x20e4); return d; } // Logger status data (sequence number)
// MULT SAXI DMA engine control. Of 4 channels only one (number 0) is currently used - for the event logger
void set_x393_mult_saxi_status_ctrl (x393_status_ctrl_t d){writel(d.d32, mmio_ptr + 0x1ce0);} // MULT_SAXI status control mode (status provides current DWORD pointer)
x393_status_ctrl_t get_x393_mult_saxi_status_ctrl (void) { x393_status_ctrl_t d; d.d32 = readl(mmio_ptr + 0x1ce0); return d; }
void x393_mult_saxi_buf_address (x393_mult_saxi_al_t d, int chn){writel(d.d32, mmio_ptr + (0x1cc0 + 0x8 * chn));} // MULT_SAXI buffer start address in DWORDS
void x393_mult_saxi_buf_len (x393_mult_saxi_al_t d, int chn){writel(d.d32, mmio_ptr + (0x1cc4 + 0x8 * chn));} // MULT_SAXI buffer length in DWORDS
x393_mult_saxi_al_t x393_mult_saxi_status (int chn) { x393_mult_saxi_al_t d; d.d32 = readl(mmio_ptr + (0x20d0 + 0x4 * chn)); return d; } // MULT_SAXI current DWORD pointer
// MULTI_CLK - global clock generation PLLs. Interface provided for debugging, no interaction is needed for normal operation
void set_x393_multiclk_status_ctrl (x393_status_ctrl_t d){writel(d.d32, mmio_ptr + 0x1ca4);} // MULTI_CLK status generation (do not use or do not set auto)
x393_status_ctrl_t get_x393_multiclk_status_ctrl (void) { x393_status_ctrl_t d; d.d32 = readl(mmio_ptr + 0x1ca4); return d; }
void set_x393_multiclk_ctrl (x393_multiclk_ctl_t d){writel(d.d32, mmio_ptr + 0x1ca0);} // MULTI_CLK reset and power down control
x393_multiclk_ctl_t get_x393_multiclk_ctrl (void) { x393_multiclk_ctl_t d; d.d32 = readl(mmio_ptr + 0x1ca0); return d; }
x393_multiclk_status_t x393_multiclk_status (void) { x393_multiclk_status_t d; d.d32 = readl(mmio_ptr + 0x20e8); return d; } // MULTI_CLK lock and toggle state
// 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.
void set_x393_debug_status_ctrl (x393_status_ctrl_t d){writel(d.d32, mmio_ptr + 0x1c48);} // Debug ring status generation - set to auto(3) if used
x393_status_ctrl_t get_x393_debug_status_ctrl (void) { x393_status_ctrl_t d; d.d32 = readl(mmio_ptr + 0x1c48); return d; }
void x393_debug_load (void) {writel(0, mmio_ptr + 0x1c44);} // Debug ring copy shift register to/from tested modules
void x393_debug_shift (u32 d) {writel(d, mmio_ptr + 0x1c40);} // Debug ring shift ring by 32 bits
x393_debug_status_t x393_debug_status (void) { x393_debug_status_t d; d.d32 = readl(mmio_ptr + 0x23f0); return d; } // Debug read status (watch sequence number)
u32 x393_debug_read (void) { u32 d; d = readl(mmio_ptr + 0x23f4); return d; } // Debug read DWORD form ring register
// Write-only addresses to program memory channel 3 (test channel)
void x393_mcntrl_chn3_scanline_mode (x393_mcntrl_mode_scan_t d){writel(d.d32, mmio_ptr + 0x04c0);} // Set mode register (write last after other channel registers are set)
void set_x393_mcntrl_chn3_scanline_status_cntrl(x393_status_ctrl_t d){writel(d.d32, mmio_ptr + 0x04c4);} // Set status control register (status update mode)
x393_status_ctrl_t get_x393_mcntrl_chn3_scanline_status_cntrl(void) { x393_status_ctrl_t d; d.d32 = readl(mmio_ptr + 0x04c4); return d; }
void x393_mcntrl_chn3_scanline_startaddr (x393_mcntrl_window_frame_sa_t d){writel(d.d32, mmio_ptr + 0x04c8);} // Set frame start address
void x393_mcntrl_chn3_scanline_frame_size(x393_mcntrl_window_frame_sa_inc_t d){writel(d.d32, mmio_ptr + 0x04cc);} // Set frame size (address increment)
void x393_mcntrl_chn3_scanline_frame_last(x393_mcntrl_window_last_frame_num_t d){writel(d.d32, mmio_ptr + 0x04d0);} // Set last frame number (number of frames in buffer minus 1)
void x393_mcntrl_chn3_scanline_frame_full_width(x393_mcntrl_window_full_width_t d){writel(d.d32, mmio_ptr + 0x04d4);} // Set frame full(padded) width
void x393_mcntrl_chn3_scanline_window_wh (x393_mcntrl_window_width_height_t d){writel(d.d32, mmio_ptr + 0x04d8);} // Set frame window size
void x393_mcntrl_chn3_scanline_window_x0y0(x393_mcntrl_window_left_top_t d){writel(d.d32, mmio_ptr + 0x04dc);} // Set frame position
void x393_mcntrl_chn3_scanline_startxy (x393_mcntrl_window_startx_starty_t d){writel(d.d32, mmio_ptr + 0x04e0);} // Set startXY register
// Write-only addresses to program memory channel 2 (test channel)
void x393_mcntrl_chn2_tiled_mode (x393_mcntrl_mode_scan_t d){writel(d.d32, mmio_ptr + 0x0500);} // Set mode register (write last after other channel registers are set)
void set_x393_mcntrl_chn2_tiled_status_cntrl(x393_status_ctrl_t d){writel(d.d32, mmio_ptr + 0x0504);} // Set status control register (status update mode)
x393_status_ctrl_t get_x393_mcntrl_chn2_tiled_status_cntrl(void) { x393_status_ctrl_t d; d.d32 = readl(mmio_ptr + 0x0504); return d; }
void x393_mcntrl_chn2_tiled_startaddr (x393_mcntrl_window_frame_sa_t d){writel(d.d32, mmio_ptr + 0x0508);} // Set frame start address
void x393_mcntrl_chn2_tiled_frame_size (x393_mcntrl_window_frame_sa_inc_t d){writel(d.d32, mmio_ptr + 0x050c);} // Set frame size (address increment)
void x393_mcntrl_chn2_tiled_frame_last (x393_mcntrl_window_last_frame_num_t d){writel(d.d32, mmio_ptr + 0x0510);} // Set last frame number (number of frames in buffer minus 1)
void x393_mcntrl_chn2_tiled_frame_full_width(x393_mcntrl_window_full_width_t d){writel(d.d32, mmio_ptr + 0x0514);} // Set frame full(padded) width
void x393_mcntrl_chn2_tiled_window_wh (x393_mcntrl_window_width_height_t d){writel(d.d32, mmio_ptr + 0x0518);} // Set frame window size
void x393_mcntrl_chn2_tiled_window_x0y0 (x393_mcntrl_window_left_top_t d){writel(d.d32, mmio_ptr + 0x051c);} // Set frame position
void x393_mcntrl_chn2_tiled_startxy (x393_mcntrl_window_startx_starty_t d){writel(d.d32, mmio_ptr + 0x0520);} // Set startXY register
void x393_mcntrl_chn2_tiled_tile_whs (x393_mcntrl_window_tile_whs_t d){writel(d.d32, mmio_ptr + 0x0524);} // Set tile size/step (tiled mode only)
// Write-only addresses to program memory channel 4 (test channel)
void x393_mcntrl_chn4_tiled_mode (x393_mcntrl_mode_scan_t d){writel(d.d32, mmio_ptr + 0x0540);} // Set mode register (write last after other channel registers are set)
void set_x393_mcntrl_chn4_tiled_status_cntrl(x393_status_ctrl_t d){writel(d.d32, mmio_ptr + 0x0544);} // Set status control register (status update mode)
x393_status_ctrl_t get_x393_mcntrl_chn4_tiled_status_cntrl(void) { x393_status_ctrl_t d; d.d32 = readl(mmio_ptr + 0x0544); return d; }
void x393_mcntrl_chn4_tiled_startaddr (x393_mcntrl_window_frame_sa_t d){writel(d.d32, mmio_ptr + 0x0548);} // Set frame start address
void x393_mcntrl_chn4_tiled_frame_size (x393_mcntrl_window_frame_sa_inc_t d){writel(d.d32, mmio_ptr + 0x054c);} // Set frame size (address increment)
void x393_mcntrl_chn4_tiled_frame_last (x393_mcntrl_window_last_frame_num_t d){writel(d.d32, mmio_ptr + 0x0550);} // Set last frame number (number of frames in buffer minus 1)
void x393_mcntrl_chn4_tiled_frame_full_width(x393_mcntrl_window_full_width_t d){writel(d.d32, mmio_ptr + 0x0554);} // Set frame full(padded) width
void x393_mcntrl_chn4_tiled_window_wh (x393_mcntrl_window_width_height_t d){writel(d.d32, mmio_ptr + 0x0558);} // Set frame window size
void x393_mcntrl_chn4_tiled_window_x0y0 (x393_mcntrl_window_left_top_t d){writel(d.d32, mmio_ptr + 0x055c);} // Set frame position
void x393_mcntrl_chn4_tiled_startxy (x393_mcntrl_window_startx_starty_t d){writel(d.d32, mmio_ptr + 0x0560);} // Set startXY register
void x393_mcntrl_chn4_tiled_tile_whs (x393_mcntrl_window_tile_whs_t d){writel(d.d32, mmio_ptr + 0x0564);} // Set tile size/step (tiled mode only)
/*******************************************************************************
* File: x393.h
* Date: 2016-04-06
* Author: auto-generated file, see x393_export_c.py
* Description: Constants definitions and functions declarations to access x393 hardware registers
*******************************************************************************/
#include "x393_types.h"
//#include "elphel/x393_defs.h // alternative variant"
// See elphel/x393_map.h for the ordered list of all I/O register addresses used
// init_mmio_ptr() should be called once before using any of the other declared functions
int init_mmio_ptr(void);
// R/W addresses to set up memory arbiter priorities. For sensors (chn = 8..11), for compressors - 12..15
void set_x393_mcntrl_arbiter_priority (x393_arbite_pri_t d, int chn); // Set memory arbiter priority (currently r/w, may become just wo)
x393_arbite_pri_t get_x393_mcntrl_arbiter_priority (int chn);
// Enable/disable memory channels (bits in a 16-bit word). For sensors (chn = 8..11), for compressors - 12..15
void set_x393_mcntrl_chn_en (x393_mcntr_chn_en_t d); // Enable/disable memory channels (currently r/w, may become just wo)
x393_mcntr_chn_en_t get_x393_mcntrl_chn_en (void);
void set_x393_mcntrl_dqs_dqm_patt (x393_mcntr_dqs_dqm_patt_t d); // Setup DQS and DQM patterns
x393_mcntr_dqs_dqm_patt_t get_x393_mcntrl_dqs_dqm_patt (void);
void set_x393_mcntrl_dq_dqs_tri (x393_mcntr_dqs_dqm_tri_t d); // Setup DQS and DQ on/off sequence
x393_mcntr_dqs_dqm_tri_t get_x393_mcntrl_dq_dqs_tri (void);
// Following enable/disable addresses can be written with any data, only addresses matter
void x393_mcntrl_dis (void); // Disable DDR3 memory controller
void x393_mcntrl_en (void); // Enable DDR3 memory controller
void x393_mcntrl_refresh_dis (void); // Disable DDR3 memory refresh
void x393_mcntrl_refresh_en (void); // Enable DDR3 memory refresh
void x393_mcntrl_sdrst_dis (void); // Disable DDR3 memory reset
void x393_mcntrl_sdrst_en (void); // Enable DDR3 memory reset
void x393_mcntrl_cke_dis (void); // Disable DDR3 memory CKE
void x393_mcntrl_cke_en (void); // Enable DDR3 memory CKE
void x393_mcntrl_cmda_dis (void); // Disable DDR3 memory command/address lines
void x393_mcntrl_cmda_en (void); // Enable DDR3 memory command/address lines
// Set DDR3 memory controller I/O delays and other timing parameters (should use individually calibrated values)
void set_x393_mcntrl_dq_odly0 (x393_dly_t d, int chn); // Lane0 DQ output delays
x393_dly_t get_x393_mcntrl_dq_odly0 (int chn);
void set_x393_mcntrl_dq_odly1 (x393_dly_t d, int chn); // Lane1 DQ output delays
x393_dly_t get_x393_mcntrl_dq_odly1 (int chn);
void set_x393_mcntrl_dq_idly0 (x393_dly_t d, int chn); // Lane0 DQ input delays
x393_dly_t get_x393_mcntrl_dq_idly0 (int chn);
void set_x393_mcntrl_dq_idly1 (x393_dly_t d, int chn); // Lane1 DQ input delays
x393_dly_t get_x393_mcntrl_dq_idly1 (int chn);
void set_x393_mcntrl_dqs_odly0 (x393_dly_t d); // Lane0 DQS output delay
x393_dly_t get_x393_mcntrl_dqs_odly0 (void);
void set_x393_mcntrl_dqs_odly1 (x393_dly_t d); // Lane1 DQS output delay
x393_dly_t get_x393_mcntrl_dqs_odly1 (void);
void set_x393_mcntrl_dqs_idly0 (x393_dly_t d); // Lane0 DQS input delay
x393_dly_t get_x393_mcntrl_dqs_idly0 (void);
void set_x393_mcntrl_dqs_idly1 (x393_dly_t d); // Lane1 DQS input delay
x393_dly_t get_x393_mcntrl_dqs_idly1 (void);
void set_x393_mcntrl_dm_odly0 (x393_dly_t d); // Lane0 DM output delay
x393_dly_t get_x393_mcntrl_dm_odly0 (void);
void set_x393_mcntrl_dm_odly1 (x393_dly_t d); // Lane1 DM output delay
x393_dly_t get_x393_mcntrl_dm_odly1 (void);
void set_x393_mcntrl_cmda_odly (x393_dly_t d, int chn); // Address, bank and commands delays
x393_dly_t get_x393_mcntrl_cmda_odly (int chn);
void set_x393_mcntrl_phase (x393_dly_t d); // Clock phase
x393_dly_t get_x393_mcntrl_phase (void);
void x393_mcntrl_dly_set (void); // Set all pre-programmed delays
void set_x393_mcntrl_wbuf_dly (x393_wbuf_dly_t d); // Set write buffer delay
x393_wbuf_dly_t get_x393_mcntrl_wbuf_dly (void);
// Write-only addresses to program memory channels for sensors (chn = 0..3), memory channels 8..11
void x393_sens_mcntrl_scanline_mode (x393_mcntrl_mode_scan_t d, int chn); // Set mode register (write last after other channel registers are set)
void set_x393_sens_mcntrl_scanline_status_cntrl(x393_status_ctrl_t d, int chn); // Set status control register (status update mode)
x393_status_ctrl_t get_x393_sens_mcntrl_scanline_status_cntrl(int chn);
void x393_sens_mcntrl_scanline_startaddr (x393_mcntrl_window_frame_sa_t d, int chn); // Set frame start address
void x393_sens_mcntrl_scanline_frame_size(x393_mcntrl_window_frame_sa_inc_t d, int chn); // Set frame size (address increment)
void x393_sens_mcntrl_scanline_frame_last(x393_mcntrl_window_last_frame_num_t d, int chn); // Set last frame number (number of frames in buffer minus 1)
void x393_sens_mcntrl_scanline_frame_full_width(x393_mcntrl_window_full_width_t d, int chn); // Set frame full(padded) width
void x393_sens_mcntrl_scanline_window_wh (x393_mcntrl_window_width_height_t d, int chn); // Set frame window size
void x393_sens_mcntrl_scanline_window_x0y0(x393_mcntrl_window_left_top_t d, int chn); // Set frame position
void x393_sens_mcntrl_scanline_startxy (x393_mcntrl_window_startx_starty_t d, int chn); // Set startXY register
// Write-only addresses to program memory channels for compressors (chn = 0..3), memory channels 12..15
void x393_sens_mcntrl_tiled_mode (x393_mcntrl_mode_scan_t d, int chn); // Set mode register (write last after other channel registers are set)
void set_x393_sens_mcntrl_tiled_status_cntrl(x393_status_ctrl_t d, int chn); // Set status control register (status update mode)
x393_status_ctrl_t get_x393_sens_mcntrl_tiled_status_cntrl(int chn);
void x393_sens_mcntrl_tiled_startaddr (x393_mcntrl_window_frame_sa_t d, int chn); // Set frame start address
void x393_sens_mcntrl_tiled_frame_size (x393_mcntrl_window_frame_sa_inc_t d, int chn); // Set frame size (address increment)
void x393_sens_mcntrl_tiled_frame_last (x393_mcntrl_window_last_frame_num_t d, int chn); // Set last frame number (number of frames in buffer minus 1)
void x393_sens_mcntrl_tiled_frame_full_width(x393_mcntrl_window_full_width_t d, int chn); // Set frame full(padded) width
void x393_sens_mcntrl_tiled_window_wh (x393_mcntrl_window_width_height_t d, int chn); // Set frame window size
void x393_sens_mcntrl_tiled_window_x0y0 (x393_mcntrl_window_left_top_t d, int chn); // Set frame position
void x393_sens_mcntrl_tiled_startxy (x393_mcntrl_window_startx_starty_t d, int chn); // Set startXY register
void x393_sens_mcntrl_tiled_tile_whs (x393_mcntrl_window_tile_whs_t d, int chn); // Set tile size/step (tiled mode only)
// Write-only addresses to program memory channel for membridge, memory channel 1
void x393_membridge_scanline_mode (x393_mcntrl_mode_scan_t d); // Set mode register (write last after other channel registers are set)
void set_x393_membridge_scanline_status_cntrl(x393_status_ctrl_t d); // Set status control register (status update mode)
x393_status_ctrl_t get_x393_membridge_scanline_status_cntrl(void);
void x393_membridge_scanline_startaddr (x393_mcntrl_window_frame_sa_t d); // Set frame start address
void x393_membridge_scanline_frame_size (x393_mcntrl_window_frame_sa_inc_t d); // Set frame size (address increment)
void x393_membridge_scanline_frame_last (x393_mcntrl_window_last_frame_num_t d); // Set last frame number (number of frames in buffer minus 1)
void x393_membridge_scanline_frame_full_width(x393_mcntrl_window_full_width_t d); // Set frame full(padded) width
void x393_membridge_scanline_window_wh (x393_mcntrl_window_width_height_t d); // Set frame window size
void x393_membridge_scanline_window_x0y0 (x393_mcntrl_window_left_top_t d); // Set frame position
void x393_membridge_scanline_startxy (x393_mcntrl_window_startx_starty_t d); // Set startXY register
void x393_membridge_ctrl (x393_membridge_cmd_t d); // Issue membridge command
void set_x393_membridge_status_cntrl (x393_status_ctrl_t d); // Set membridge status control register
x393_status_ctrl_t get_x393_membridge_status_cntrl (void);
void x393_membridge_lo_addr64 (u29_t d); // start address of the system memory range in QWORDs (4 LSBs==0)
void x393_membridge_size64 (u29_t d); // size of the system memory range in QWORDs (4 LSBs==0), rolls over
void x393_membridge_start64 (u29_t d); // start of transfer offset to system memory range in QWORDs (4 LSBs==0)
void x393_membridge_len64 (u29_t d); // Full length of transfer in QWORDs
void x393_membridge_width64 (u29_t d); // Frame width in QWORDs (last xfer in each line may be partial)
void x393_membridge_mode (x393_membridge_mode_t d); // AXI cache mode
// Write-only addresses to PS PIO (Software generated DDR3 memory access sequences)
void x393_mcntrl_ps_en_rst (x393_ps_pio_en_rst_t d); // Set PS PIO enable and reset
void x393_mcntrl_ps_cmd (x393_ps_pio_cmd_t d); // Set PS PIO commands
void set_x393_mcntrl_ps_status_cntrl (x393_status_ctrl_t d); // Set PS PIO status control register (status update mode)
x393_status_ctrl_t get_x393_mcntrl_ps_status_cntrl (void);
// Write-only addresses to to program status report mode for memory controller
void set_x393_mcontr_phy_status_cntrl (x393_status_ctrl_t d); // Set status control register (status update mode)
x393_status_ctrl_t get_x393_mcontr_phy_status_cntrl (void);
void set_x393_mcontr_top_16bit_status_cntrl(x393_status_ctrl_t d); // Set status control register (status update mode)
x393_status_ctrl_t get_x393_mcontr_top_16bit_status_cntrl(void);
// Write-only addresses to to program status report mode for test channels
void set_x393_mcntrl_test01_chn2_status_cntrl(x393_status_ctrl_t d); // Set status control register (status update mode)
x393_status_ctrl_t get_x393_mcntrl_test01_chn2_status_cntrl(void);
void set_x393_mcntrl_test01_chn3_status_cntrl(x393_status_ctrl_t d); // Set status control register (status update mode)
x393_status_ctrl_t get_x393_mcntrl_test01_chn3_status_cntrl(void);
void set_x393_mcntrl_test01_chn4_status_cntrl(x393_status_ctrl_t d); // Set status control register (status update mode)
x393_status_ctrl_t get_x393_mcntrl_test01_chn4_status_cntrl(void);
// Write-only addresses for test channels commands
void x393_mcntrl_test01_chn2_mode (x393_test01_mode_t d); // Set command for test01 channel 2
void x393_mcntrl_test01_chn3_mode (x393_test01_mode_t d); // Set command for test01 channel 3
void x393_mcntrl_test01_chn4_mode (x393_test01_mode_t d); // Set command for test01 channel 4
// Read-only addresses for status information
x393_status_mcntrl_phy_t x393_mcontr_phy_status (void); // Status register for MCNTRL PHY
x393_status_mcntrl_top_t x393_mcontr_top_status (void); // Status register for MCNTRL requests
x393_status_mcntrl_ps_t x393_mcntrl_ps_status (void); // Status register for MCNTRL software R/W
x393_status_mcntrl_lintile_t x393_mcntrl_chn1_status (void); // Status register for MCNTRL CHN1 (membridge)
x393_status_mcntrl_lintile_t x393_mcntrl_chn3_status (void); // Status register for MCNTRL CHN3 (scanline)
x393_status_mcntrl_lintile_t x393_mcntrl_chn2_status (void); // Status register for MCNTRL CHN2 (tiled)
x393_status_mcntrl_lintile_t x393_mcntrl_chn4_status (void); // Status register for MCNTRL CHN4 (tiled)
x393_status_mcntrl_testchn_t x393_test01_chn2_status (void); // Status register for test channel 2
x393_status_mcntrl_testchn_t x393_test01_chn3_status (void); // Status register for test channel 3
x393_status_mcntrl_testchn_t x393_test01_chn4_status (void); // Status register for test channel 4
x393_status_membridge_t x393_membridge_status (void); // Status register for membridge
// Write-only control of the sensor channels
void x393_sens_mode (x393_sens_mode_t d, int sens_num); // Write sensor channel mode
void x393_sensi2c_ctrl (x393_i2c_ctltbl_t d, int sens_num); // Control sensor i2c, write i2c LUT
void set_x393_sensi2c_status_ctrl (x393_status_ctrl_t d, int sens_num); // Setup sensor i2c status report mode
x393_status_ctrl_t get_x393_sensi2c_status_ctrl (int sens_num);
void x393_sens_sync_mult (x393_sens_sync_mult_t d, int sens_num); // Configure frames combining
void x393_sens_sync_late (x393_sens_sync_late_t d, int sens_num); // Configure frame sync delay
void x393_sensio_ctrl (x393_sensio_ctl_t d, int sens_num); // Configure sensor I/O port
void set_x393_sensio_status_cntrl (x393_status_ctrl_t d, int sens_num); // Set status control for SENSIO module
x393_status_ctrl_t get_x393_sensio_status_cntrl (int sens_num);
void x393_sensio_jtag (x393_sensio_jtag_t d, int sens_num); // Programming interface for multiplexer FPGA (with X393_SENSIO_STATUS)
void set_x393_sensio_width (x393_sensio_width_t d, int sens_num); // Set sensor line in pixels (0 - use line sync from the sensor)
x393_sensio_width_t get_x393_sensio_width (int sens_num);
void set_x393_sensio_tim0 (x393_sensio_tim0_t d, int sens_num); // Sensor port i/o timing configuration, register 0
x393_sensio_tim0_t get_x393_sensio_tim0 (int sens_num);
void set_x393_sensio_tim1 (x393_sensio_tim1_t d, int sens_num); // Sensor port i/o timing configuration, register 1
x393_sensio_tim1_t get_x393_sensio_tim1 (int sens_num);
void set_x393_sensio_tim2 (x393_sensio_tim2_t d, int sens_num); // Sensor port i/o timing configuration, register 2
x393_sensio_tim2_t get_x393_sensio_tim2 (int sens_num);
void set_x393_sensio_tim3 (x393_sensio_tim3_t d, int sens_num); // Sensor port i/o timing configuration, register 3
x393_sensio_tim3_t get_x393_sensio_tim3 (int sens_num);
// 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
void x393_sensi2c_abs (u32 d, int sens_num, int offset); // Write sensor i2c sequencer
void x393_sensi2c_rel (u32 d, int sens_num, int offset); // Write sensor i2c sequencer
// Lens vignetting correction (for each sub-frame separately)
void set_x393_lens_height0_m1 (x393_lens_height_m1_t d, int sens_num); // Subframe 0 height minus 1
x393_lens_height_m1_t get_x393_lens_height0_m1 (int sens_num);
void set_x393_lens_height1_m1 (x393_lens_height_m1_t d, int sens_num); // Subframe 1 height minus 1
x393_lens_height_m1_t get_x393_lens_height1_m1 (int sens_num);
void set_x393_lens_height2_m1 (x393_lens_height_m1_t d, int sens_num); // Subframe 2 height minus 1
x393_lens_height_m1_t get_x393_lens_height2_m1 (int sens_num);
void x393_lens_corr_cnh_addr_data (x393_lens_corr_t d, int sens_num); // Combined address/data to write lens vignetting correction coefficients
// Lens vignetting coefficient addresses - use with x393_lens_corr_wo_t (X393_LENS_CORR_CNH_ADDR_DATA)
#define X393_LENS_AX 0x00000000 // Address of correction parameter Ax
#define X393_LENS_AX_MASK 0x000000f8 // Correction parameter Ax mask
#define X393_LENS_AY 0x00000008 // Address of correction parameter Ay
#define X393_LENS_AY_MASK 0x000000f8 // Correction parameter Ay mask
#define X393_LENS_C 0x00000010 // Address of correction parameter C
#define X393_LENS_C_MASK 0x000000f8 // Correction parameter C mask
#define X393_LENS_BX 0x00000020 // Address of correction parameter Bx
#define X393_LENS_BX_MASK 0x000000e0 // Correction parameter Bx mask
#define X393_LENS_BY 0x00000040 // Address of correction parameter By
#define X393_LENS_BY_MASK 0x000000e0 // Correction parameter By mask
#define X393_LENS_SCALE0 0x00000060 // Address of correction parameter scale0
#define X393_LENS_SCALE1 0x00000062 // Address of correction parameter scale1
#define X393_LENS_SCALE2 0x00000064 // Address of correction parameter scale2
#define X393_LENS_SCALE3 0x00000066 // Address of correction parameter scale3
#define X393_LENS_SCALES_MASK 0x000000f8 // Common mask for scales
#define X393_LENS_FAT0_IN 0x00000068 // Address of input fat zero parameter (to subtract from input)
#define X393_LENS_FAT0_IN_MASK 0x000000ff // Mask for fat zero input parameter
#define X393_LENS_FAT0_OUT 0x00000069 // Address of output fat zero parameter (to add to output)
#define X393_LENS_FAT0_OUT_MASK 0x000000ff // Mask for fat zero output parameters
#define X393_LENS_POST_SCALE 0x0000006a // Address of post scale (shift output) parameter
#define X393_LENS_POST_SCALE_MASK 0x000000ff // Mask for post scale parameter
// Sensor gamma conversion control (See Python code for examples of the table data generation)
void set_x393_sens_gamma_ctrl (x393_gamma_ctl_t d, int sens_num); // Gamma module control
x393_gamma_ctl_t get_x393_sens_gamma_ctrl (int sens_num);
void x393_sens_gamma_tbl (x393_gamma_tbl_t d, int sens_num); // Write sensor gamma table address/data (with autoincrement)
void set_x393_sens_gamma_height01m1 (x393_gamma_height01m1_t d, int sens_num); // Gamma module subframes 0,1 heights minus 1
x393_gamma_height01m1_t get_x393_sens_gamma_height01m1 (int sens_num);
void set_x393_sens_gamma_height2m1 (x393_gamma_height2m1_t d, int sens_num); // Gamma module subframe 2 height minus 1
x393_gamma_height2m1_t get_x393_sens_gamma_height2m1 (int sens_num);
// Windows for histogram subchannels
void set_x393_histogram_lt0 (x393_hist_left_top_t d, int sens_num); // Specify histogram 0 left/top
x393_hist_left_top_t get_x393_histogram_lt0 (int sens_num);
void set_x393_histogram_wh0 (x393_hist_width_height_m1_t d, int sens_num); // Specify histogram 0 width/height
x393_hist_width_height_m1_t get_x393_histogram_wh0 (int sens_num);
void set_x393_histogram_lt1 (x393_hist_left_top_t d, int sens_num); // Specify histogram 1 left/top
x393_hist_left_top_t get_x393_histogram_lt1 (int sens_num);
void set_x393_histogram_wh1 (x393_hist_width_height_m1_t d, int sens_num); // Specify histogram 1 width/height
x393_hist_width_height_m1_t get_x393_histogram_wh1 (int sens_num);
void set_x393_histogram_lt2 (x393_hist_left_top_t d, int sens_num); // Specify histogram 2 left/top
x393_hist_left_top_t get_x393_histogram_lt2 (int sens_num);
void set_x393_histogram_wh2 (x393_hist_width_height_m1_t d, int sens_num); // Specify histogram 2 width/height
x393_hist_width_height_m1_t get_x393_histogram_wh2 (int sens_num);
void set_x393_histogram_lt3 (x393_hist_left_top_t d, int sens_num); // Specify histogram 3 left/top
x393_hist_left_top_t get_x393_histogram_lt3 (int sens_num);
void set_x393_histogram_wh3 (x393_hist_width_height_m1_t d, int sens_num); // Specify histogram 3 width/height
x393_hist_width_height_m1_t get_x393_histogram_wh3 (int sens_num);
// DMA control for the histograms. Subchannel here is 4*sensor_port+ histogram_subchannel
void set_x393_hist_saxi_mode (x393_hist_saxi_mode_t d); // Histogram DMA operation mode
x393_hist_saxi_mode_t get_x393_hist_saxi_mode (void);
void set_x393_hist_saxi_addr (x393_hist_saxi_addr_t d, int subchannel); // Histogram DMA addresses (in 4096 byte pages)
x393_hist_saxi_addr_t get_x393_hist_saxi_addr (int subchannel);
// Read-only addresses for sensors status information
x393_status_sens_i2c_t x393_sensi2c_status (int sens_num); // Status of the sensors i2c
x393_status_sens_io_t x393_sensio_status (int sens_num); // Status of the sensor ports I/O pins
// Compressor bitfields values
#define X393_CMPRS_CBIT_RUN_RST 0x00000000 // Reset compressor, stop immediately
#define X393_CMPRS_CBIT_RUN_DISABLE 0x00000001 // Disable compression of the new frames, finish any already started
#define X393_CMPRS_CBIT_RUN_STANDALONE 0x00000002 // Enable compressor, compress single frame from memory (async)
#define X393_CMPRS_CBIT_RUN_ENABLE 0x00000003 // Enable synchronous compression mode
#define X393_CMPRS_CBIT_CMODE_JPEG18 0x00000000 // Color 4:2:0 3x3 de-bayer core
#define X393_CMPRS_CBIT_CMODE_MONO6 0x00000001 // Mono 4:2:0 (6 blocks)
#define X393_CMPRS_CBIT_CMODE_JP46 0x00000002 // jp4, 6 blocks, original
#define X393_CMPRS_CBIT_CMODE_JP46DC 0x00000003 // jp4, 6 blocks, DC-improved
#define X393_CMPRS_CBIT_CMODE_JPEG20 0x00000004 // Color 4:2:0 with 5x5 de-bayer (not implemented)
#define X393_CMPRS_CBIT_CMODE_JP4 0x00000005 // jp4, 4 blocks
#define X393_CMPRS_CBIT_CMODE_JP4DC 0x00000006 // jp4, 4 blocks, DC-improved
#define X393_CMPRS_CBIT_CMODE_JP4DIFF 0x00000007 // jp4, 4 blocks, differential
#define X393_CMPRS_CBIT_CMODE_JP4DIFFHDR 0x00000008 // jp4, 4 blocks, differential, hdr
#define X393_CMPRS_CBIT_CMODE_JP4DIFFDIV2 0x00000009 // jp4, 4 blocks, differential, divide by 2
#define X393_CMPRS_CBIT_CMODE_JP4DIFFHDRDIV2 0x0000000a // jp4, 4 blocks, differential, hdr,divide by 2
#define X393_CMPRS_CBIT_CMODE_MONO1 0x0000000b // Mono JPEG (not yet implemented)
#define X393_CMPRS_CBIT_CMODE_MONO4 0x0000000e // Mono, 4 blocks (2x2 macroblocks)
#define X393_CMPRS_CBIT_CMODE_JPEG18 0x00000000 // Color 4:2:0
#define X393_CMPRS_CBIT_FRAMES_SINGLE 0x00000000 // Use single-frame buffer
#define X393_CMPRS_CBIT_FRAMES_MULTI 0x00000001 // Use multi-frame buffer
// Compressor control
void x393_cmprs_control_reg (x393_cmprs_mode_t d, int cmprs_chn); // Program compressor channel operation mode
void set_x393_cmprs_status (x393_status_ctrl_t d, int cmprs_chn); // Setup compressor status report mode
x393_status_ctrl_t get_x393_cmprs_status (int cmprs_chn);
void set_x393_cmprs_format (x393_cmprs_frame_format_t d, int cmprs_chn); // Compressor frame format
x393_cmprs_frame_format_t get_x393_cmprs_format (int cmprs_chn);
void set_x393_cmprs_color_saturation (x393_cmprs_colorsat_t d, int cmprs_chn); // Compressor color saturation
x393_cmprs_colorsat_t get_x393_cmprs_color_saturation (int cmprs_chn);
void set_x393_cmprs_coring_mode (x393_cmprs_coring_mode_t d, int cmprs_chn); // Select coring mode
x393_cmprs_coring_mode_t get_x393_cmprs_coring_mode (int cmprs_chn);
void x393_cmprs_interrupts (x393_cmprs_interrupts_t d, int cmprs_chn); // 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
#define X393_TABLE_QUANTIZATION_TYPE 0x00000000 // Quantization table type
#define X393_TABLE_CORING_TYPE 0x00000001 // Coring table type
#define X393_TABLE_FOCUS_TYPE 0x00000002 // Focus table type
#define X393_TABLE_HUFFMAN_TYPE 0x00000003 // Huffman table type
// Compressor tables control
void x393_cmprs_tables_data (u32 d, int cmprs_chn); // Compressor tables data
void x393_cmprs_tables_address (x393_cmprs_table_addr_t d, int cmprs_chn); // Compressor tables type/address
// Compressor channel status)
x393_cmprs_status_t x393_cmprs_status (int chn); // Status of the compressor channel (incl. interrupt
u32 x393_cmprs_hifreq (int chn); // Focus helper high-frequency amount
// 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
void x393_afimux0_en (x393_afimux_en_t d); // AFI MUX 0 global/port run/pause control
void set_x393_afimux0_rst (x393_afimux_rst_t d); // AFI MUX 0 per-port resets
x393_afimux_rst_t get_x393_afimux0_rst (void);
void x393_afimux0_report_mode (x393_afimux_report_t d); // AFI MUX 0 readout pointer report mode
void set_x393_afimux0_status_control (x393_status_ctrl_t d); // AFI MUX 0 status report mode
x393_status_ctrl_t get_x393_afimux0_status_control (void);
void set_x393_afimux0_sa (x393_afimux_sa_t d, int afi_port); // AFI MUX 0 DMA buffer start address in 32-byte blocks
x393_afimux_sa_t get_x393_afimux0_sa (int afi_port);
void set_x393_afimux0_len (x393_afimux_len_t d, int afi_port); // AFI MUX 0 DMA buffer length in 32-byte blocks
x393_afimux_len_t get_x393_afimux0_len (int afi_port);
// Same for the second AXI HP channel (not currently used)
void x393_afimux1_en (x393_afimux_en_t d); // AFI MUX 1 global/port run/pause control
void set_x393_afimux1_rst (x393_afimux_rst_t d); // AFI MUX 1 per-port resets
x393_afimux_rst_t get_x393_afimux1_rst (void);
void x393_afimux1_report_mode (x393_afimux_report_t d); // AFI MUX 1 readout pointer report mode
void set_x393_afimux1_status_control (x393_status_ctrl_t d); // AFI MUX 1 status report mode
x393_status_ctrl_t get_x393_afimux1_status_control (void);
void set_x393_afimux1_sa (x393_afimux_sa_t d, int afi_port); // AFI MUX 1 DMA buffer start address in 32-byte blocks
x393_afimux_sa_t get_x393_afimux1_sa (int afi_port);
void set_x393_afimux1_len (x393_afimux_len_t d, int afi_port); // AFI MUX 1 DMA buffer length in 32-byte blocks
x393_afimux_len_t get_x393_afimux1_len (int afi_port);
// Read-only sensors status information (pointer offset and last sequence number)
x393_afimux_status_t x393_afimux0_status (int afi_port); // Status of the AFI MUX 0 (including image pointer)
x393_afimux_status_t x393_afimux1_status (int afi_port); // Status of the AFI MUX 1 (including image pointer)
//
// 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
void x393_gpio_set_pins (x393_gpio_set_pins_t d); // State of the GPIO pins and seq. number
void set_x393_gpio_status_control (x393_status_ctrl_t d); // GPIO status control mode
x393_status_ctrl_t get_x393_gpio_status_control (void);
// Read-only GPIO pins state
x393_gpio_status_t x393_gpio_status (void); // State of the GPIO pins and seq. number
// RTC control
void set_x393_rtc_usec (x393_rtc_usec_t d); // RTC microseconds
x393_rtc_usec_t get_x393_rtc_usec (void);
void set_x393_rtc_sec_set (x393_rtc_sec_t d); // RTC seconds and set clock
x393_rtc_sec_t get_x393_rtc_sec_set (void);
void set_x393_rtc_corr (x393_rtc_corr_t d); // RTC correction (+/- 1/256 full scale)
x393_rtc_corr_t get_x393_rtc_corr (void);
void set_x393_rtc_set_status (x393_status_ctrl_t d); // RTC status control mode, write makes a snapshot to be read out
x393_status_ctrl_t get_x393_rtc_set_status (void);
// Read-only RTC state
x393_rtc_status_t x393_rtc_status (void); // RTC status reg
x393_rtc_sec_t x393_rtc_status_sec (void); // RTC snapshot seconds
x393_rtc_usec_t x393_rtc_status_usec (void); // RTC snapshot microseconds
// CAMSYNC control
void x393_camsync_mode (x393_camsync_mode_t d); // CAMSYNC mode
void x393_camsync_trig_src (x393_camsync_io_t d); // CAMSYNC trigger source
void x393_camsync_trig_dst (x393_camsync_io_t d); // CAMSYNC trigger destination
// 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
void set_x393_camsync_trig_period (u32 d); // CAMSYNC trigger period
u32 get_x393_camsync_trig_period (void);
void set_x393_camsync_trig_delay (u32 d, int sens_chn); // CAMSYNC trigger delay
u32 get_x393_camsync_trig_delay (int sens_chn);
// Command sequencer control
// Controller is programmed through 32 locations. Each registers but the control require two writes:
// 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
void x393_cmdframeseq_ctrl (x393_cmdframeseq_mode_t d, int sens_chn); // CMDFRAMESEQ control register
void x393_cmdframeseq_abs (u32 d, int sens_chn, int offset); // CMDFRAMESEQ absolute frame address/command
void x393_cmdframeseq_rel (u32 d, int sens_chn, int offset); // CMDFRAMESEQ relative frame address/command
// Command sequencer multiplexer, provides current frame number for each sensor channel and interrupt status/interrupt masks for them.
// Interrupts and interrupt masks are controlled through channel CMDFRAMESEQ module
void set_x393_cmdseqmux_status_ctrl (x393_status_ctrl_t d); // CMDSEQMUX status control mode (status provides current frame numbers)
x393_status_ctrl_t get_x393_cmdseqmux_status_ctrl (void);
x393_cmdseqmux_status_t x393_cmdseqmux_status (void); // CMDSEQMUX status data (frame numbers and interrupts
// Event logger
// Event logger configuration/data is writtent to the module ising two 32-bit register locations : data and address.
// Address consists of 2 parts - 2-bit page (configuration, imu, gps, message) and a 5-bit sub-address autoincremented when writing data.
// Register pages:
#define X393_LOGGER_PAGE_CONF 0x00000000 // Logger configuration page
#define X393_LOGGER_PAGE_IMU 0x00000003 // Logger IMU parameters page
#define X393_LOGGER_PAGE_GPS 0x00000001 // Logger GPS parameters page
#define X393_LOGGER_PAGE_MSG 0x00000002 // Logger MSG (odometer) parameters page
// Register configuration addresses (with X393_LOGGER_PAGE_CONF):
#define X393_LOGGER_PERIOD 0x00000000 // IMU period (in SPI clocks, high word 0xffff - use IMU ready)
#define X393_LOGGER_BIT_DURATION 0x00000001 // IMU SPI bit duration (in mclk == 50 ns periods?)
#define X393_LOGGER_BIT_HALF_PERIOD 0x00000002 // Logger rs232 half bit period (in mclk == 50 ns periods?)
#define X393_LOGGER_CONFIG 0x00000003 // Logger IMU parameters page
void set_x393_logger_status_ctrl (x393_status_ctrl_t d); // Logger status configuration (to report sample number)
x393_status_ctrl_t get_x393_logger_status_ctrl (void);
void x393_logger_data (x393_logger_data_t d); // Logger register write data
void x393_logger_address (x393_logger_address_t d); // Logger register write page/address
x393_logger_status_t x393_logger_status (void); // Logger status data (sequence number)
// MULT SAXI DMA engine control. Of 4 channels only one (number 0) is currently used - for the event logger
void set_x393_mult_saxi_status_ctrl (x393_status_ctrl_t d); // MULT_SAXI status control mode (status provides current DWORD pointer)
x393_status_ctrl_t get_x393_mult_saxi_status_ctrl (void);
void x393_mult_saxi_buf_address (x393_mult_saxi_al_t d, int chn); // MULT_SAXI buffer start address in DWORDS
void x393_mult_saxi_buf_len (x393_mult_saxi_al_t d, int chn); // MULT_SAXI buffer length in DWORDS
x393_mult_saxi_al_t x393_mult_saxi_status (int chn); // MULT_SAXI current DWORD pointer
// MULTI_CLK - global clock generation PLLs. Interface provided for debugging, no interaction is needed for normal operation
void set_x393_multiclk_status_ctrl (x393_status_ctrl_t d); // MULTI_CLK status generation (do not use or do not set auto)
x393_status_ctrl_t get_x393_multiclk_status_ctrl (void);
void set_x393_multiclk_ctrl (x393_multiclk_ctl_t d); // MULTI_CLK reset and power down control
x393_multiclk_ctl_t get_x393_multiclk_ctrl (void);
x393_multiclk_status_t x393_multiclk_status (void); // MULTI_CLK lock and toggle state
// 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.
void set_x393_debug_status_ctrl (x393_status_ctrl_t d); // Debug ring status generation - set to auto(3) if used
x393_status_ctrl_t get_x393_debug_status_ctrl (void);
void x393_debug_load (void); // Debug ring copy shift register to/from tested modules
void x393_debug_shift (u32 d); // Debug ring shift ring by 32 bits
x393_debug_status_t x393_debug_status (void); // Debug read status (watch sequence number)
u32 x393_debug_read (void); // Debug read DWORD form ring register
// Write-only addresses to program memory channel 3 (test channel)
void x393_mcntrl_chn3_scanline_mode (x393_mcntrl_mode_scan_t d); // Set mode register (write last after other channel registers are set)
void set_x393_mcntrl_chn3_scanline_status_cntrl(x393_status_ctrl_t d); // Set status control register (status update mode)
x393_status_ctrl_t get_x393_mcntrl_chn3_scanline_status_cntrl(void);
void x393_mcntrl_chn3_scanline_startaddr (x393_mcntrl_window_frame_sa_t d); // Set frame start address
void x393_mcntrl_chn3_scanline_frame_size(x393_mcntrl_window_frame_sa_inc_t d); // Set frame size (address increment)
void x393_mcntrl_chn3_scanline_frame_last(x393_mcntrl_window_last_frame_num_t d); // Set last frame number (number of frames in buffer minus 1)
void x393_mcntrl_chn3_scanline_frame_full_width(x393_mcntrl_window_full_width_t d); // Set frame full(padded) width
void x393_mcntrl_chn3_scanline_window_wh (x393_mcntrl_window_width_height_t d); // Set frame window size
void x393_mcntrl_chn3_scanline_window_x0y0(x393_mcntrl_window_left_top_t d); // Set frame position
void x393_mcntrl_chn3_scanline_startxy (x393_mcntrl_window_startx_starty_t d); // Set startXY register
// Write-only addresses to program memory channel 2 (test channel)
void x393_mcntrl_chn2_tiled_mode (x393_mcntrl_mode_scan_t d); // Set mode register (write last after other channel registers are set)
void set_x393_mcntrl_chn2_tiled_status_cntrl(x393_status_ctrl_t d); // Set status control register (status update mode)
x393_status_ctrl_t get_x393_mcntrl_chn2_tiled_status_cntrl(void);
void x393_mcntrl_chn2_tiled_startaddr (x393_mcntrl_window_frame_sa_t d); // Set frame start address
void x393_mcntrl_chn2_tiled_frame_size (x393_mcntrl_window_frame_sa_inc_t d); // Set frame size (address increment)
void x393_mcntrl_chn2_tiled_frame_last (x393_mcntrl_window_last_frame_num_t d); // Set last frame number (number of frames in buffer minus 1)
void x393_mcntrl_chn2_tiled_frame_full_width(x393_mcntrl_window_full_width_t d); // Set frame full(padded) width
void x393_mcntrl_chn2_tiled_window_wh (x393_mcntrl_window_width_height_t d); // Set frame window size
void x393_mcntrl_chn2_tiled_window_x0y0 (x393_mcntrl_window_left_top_t d); // Set frame position
void x393_mcntrl_chn2_tiled_startxy (x393_mcntrl_window_startx_starty_t d); // Set startXY register
void x393_mcntrl_chn2_tiled_tile_whs (x393_mcntrl_window_tile_whs_t d); // Set tile size/step (tiled mode only)
// Write-only addresses to program memory channel 4 (test channel)
void x393_mcntrl_chn4_tiled_mode (x393_mcntrl_mode_scan_t d); // Set mode register (write last after other channel registers are set)
void set_x393_mcntrl_chn4_tiled_status_cntrl(x393_status_ctrl_t d); // Set status control register (status update mode)
x393_status_ctrl_t get_x393_mcntrl_chn4_tiled_status_cntrl(void);
void x393_mcntrl_chn4_tiled_startaddr (x393_mcntrl_window_frame_sa_t d); // Set frame start address
void x393_mcntrl_chn4_tiled_frame_size (x393_mcntrl_window_frame_sa_inc_t d); // Set frame size (address increment)
void x393_mcntrl_chn4_tiled_frame_last (x393_mcntrl_window_last_frame_num_t d); // Set last frame number (number of frames in buffer minus 1)
void x393_mcntrl_chn4_tiled_frame_full_width(x393_mcntrl_window_full_width_t d); // Set frame full(padded) width
void x393_mcntrl_chn4_tiled_window_wh (x393_mcntrl_window_width_height_t d); // Set frame window size
void x393_mcntrl_chn4_tiled_window_x0y0 (x393_mcntrl_window_left_top_t d); // Set frame position
void x393_mcntrl_chn4_tiled_startxy (x393_mcntrl_window_startx_starty_t d); // Set startXY register
void x393_mcntrl_chn4_tiled_tile_whs (x393_mcntrl_window_tile_whs_t d); // Set tile size/step (tiled mode only)
/*******************************************************************************
* File: x393_defs.h
* Date: 2016-04-06
* Author: auto-generated file, see x393_export_c.py
* Description: Constants and hardware addresses definitions to access x393 hardware registers
*******************************************************************************/
// R/W addresses to set up memory arbiter priorities. For sensors (chn = 8..11), for compressors - 12..15
#define X393_MCNTRL_ARBITER_PRIORITY(chn) (0x40000180 + 0x4 * (chn)) // Set memory arbiter priority (currently r/w, may become just wo), chn = 0..15, data type: x393_arbite_pri_t (rw)
// Enable/disable memory channels (bits in a 16-bit word). For sensors (chn = 8..11), for compressors - 12..15
#define X393_MCNTRL_CHN_EN 0x400001c0 // Enable/disable memory channels (currently r/w, may become just wo), data type: x393_mcntr_chn_en_t (rw)
#define X393_MCNTRL_DQS_DQM_PATT 0x40000140 // Setup DQS and DQM patterns, data type: x393_mcntr_dqs_dqm_patt_t (rw)
#define X393_MCNTRL_DQ_DQS_TRI 0x40000144 // Setup DQS and DQ on/off sequence, data type: x393_mcntr_dqs_dqm_tri_t (rw)
// Following enable/disable addresses can be written with any data, only addresses matter
#define X393_MCNTRL_DIS 0x400000c0 // Disable DDR3 memory controller
#define X393_MCNTRL_EN 0x400000c4 // Enable DDR3 memory controller
#define X393_MCNTRL_REFRESH_DIS 0x400000c8 // Disable DDR3 memory refresh
#define X393_MCNTRL_REFRESH_EN 0x400000cc // Enable DDR3 memory refresh
#define X393_MCNTRL_SDRST_DIS 0x40000098 // Disable DDR3 memory reset
#define X393_MCNTRL_SDRST_EN 0x4000009c // Enable DDR3 memory reset
#define X393_MCNTRL_CKE_DIS 0x400000a0 // Disable DDR3 memory CKE
#define X393_MCNTRL_CKE_EN 0x400000a4 // Enable DDR3 memory CKE
#define X393_MCNTRL_CMDA_DIS 0x40000090 // Disable DDR3 memory command/address lines
#define X393_MCNTRL_CMDA_EN 0x40000094 // Enable DDR3 memory command/address lines
// Set DDR3 memory controller I/O delays and other timing parameters (should use individually calibrated values)
#define X393_MCNTRL_DQ_ODLY0(chn) (0x40000200 + 0x4 * (chn)) // Lane0 DQ output delays , chn = 0..7, data type: x393_dly_t (rw)
#define X393_MCNTRL_DQ_ODLY1(chn) (0x40000280 + 0x4 * (chn)) // Lane1 DQ output delays , chn = 0..7, data type: x393_dly_t (rw)
#define X393_MCNTRL_DQ_IDLY0(chn) (0x40000240 + 0x4 * (chn)) // Lane0 DQ input delays , chn = 0..7, data type: x393_dly_t (rw)
#define X393_MCNTRL_DQ_IDLY1(chn) (0x400002c0 + 0x4 * (chn)) // Lane1 DQ input delays , chn = 0..7, data type: x393_dly_t (rw)
#define X393_MCNTRL_DQS_ODLY0 0x40000220 // Lane0 DQS output delay , data type: x393_dly_t (rw)
#define X393_MCNTRL_DQS_ODLY1 0x400002a0 // Lane1 DQS output delay , data type: x393_dly_t (rw)
#define X393_MCNTRL_DQS_IDLY0 0x40000260 // Lane0 DQS input delay , data type: x393_dly_t (rw)
#define X393_MCNTRL_DQS_IDLY1 0x400002e0 // Lane1 DQS input delay , data type: x393_dly_t (rw)
#define X393_MCNTRL_DM_ODLY0 0x40000224 // Lane0 DM output delay , data type: x393_dly_t (rw)
#define X393_MCNTRL_DM_ODLY1 0x400002a4 // Lane1 DM output delay , data type: x393_dly_t (rw)
#define X393_MCNTRL_CMDA_ODLY(chn) (0x40000300 + 0x4 * (chn)) // Address, bank and commands delays, chn = 0..31, data type: x393_dly_t (rw)
#define X393_MCNTRL_PHASE 0x40000380 // Clock phase, data type: x393_dly_t (rw)
#define X393_MCNTRL_DLY_SET 0x40000080 // Set all pre-programmed delays
#define X393_MCNTRL_WBUF_DLY 0x40000148 // Set write buffer delay, data type: x393_wbuf_dly_t (rw)
// Write-only addresses to program memory channels for sensors (chn = 0..3), memory channels 8..11
#define X393_SENS_MCNTRL_SCANLINE_MODE(chn) (0x40001a00 + 0x40 * (chn)) // Set mode register (write last after other channel registers are set), chn = 0..3, data type: x393_mcntrl_mode_scan_t (wo)
#define X393_SENS_MCNTRL_SCANLINE_STATUS_CNTRL(chn) (0x40001a04 + 0x40 * (chn)) // Set status control register (status update mode), chn = 0..3, data type: x393_status_ctrl_t (rw)
#define X393_SENS_MCNTRL_SCANLINE_STARTADDR(chn) (0x40001a08 + 0x40 * (chn)) // Set frame start address, chn = 0..3, data type: x393_mcntrl_window_frame_sa_t (wo)
#define X393_SENS_MCNTRL_SCANLINE_FRAME_SIZE(chn) (0x40001a0c + 0x40 * (chn)) // Set frame size (address increment), chn = 0..3, data type: x393_mcntrl_window_frame_sa_inc_t (wo)
#define X393_SENS_MCNTRL_SCANLINE_FRAME_LAST(chn) (0x40001a10 + 0x40 * (chn)) // Set last frame number (number of frames in buffer minus 1), chn = 0..3, data type: x393_mcntrl_window_last_frame_num_t (wo)
#define X393_SENS_MCNTRL_SCANLINE_FRAME_FULL_WIDTH(chn) (0x40001a14 + 0x40 * (chn)) // Set frame full(padded) width, chn = 0..3, data type: x393_mcntrl_window_full_width_t (wo)
#define X393_SENS_MCNTRL_SCANLINE_WINDOW_WH(chn) (0x40001a18 + 0x40 * (chn)) // Set frame window size, chn = 0..3, data type: x393_mcntrl_window_width_height_t (wo)
#define X393_SENS_MCNTRL_SCANLINE_WINDOW_X0Y0(chn) (0x40001a1c + 0x40 * (chn)) // Set frame position, chn = 0..3, data type: x393_mcntrl_window_left_top_t (wo)
#define X393_SENS_MCNTRL_SCANLINE_STARTXY(chn) (0x40001a20 + 0x40 * (chn)) // Set startXY register, chn = 0..3, data type: x393_mcntrl_window_startx_starty_t (wo)
// Write-only addresses to program memory channels for compressors (chn = 0..3), memory channels 12..15
#define X393_SENS_MCNTRL_TILED_MODE(chn) (0x40001b00 + 0x40 * (chn)) // Set mode register (write last after other channel registers are set), chn = 0..3, data type: x393_mcntrl_mode_scan_t (wo)
#define X393_SENS_MCNTRL_TILED_STATUS_CNTRL(chn) (0x40001b04 + 0x40 * (chn)) // Set status control register (status update mode), chn = 0..3, data type: x393_status_ctrl_t (rw)
#define X393_SENS_MCNTRL_TILED_STARTADDR(chn) (0x40001b08 + 0x40 * (chn)) // Set frame start address, chn = 0..3, data type: x393_mcntrl_window_frame_sa_t (wo)
#define X393_SENS_MCNTRL_TILED_FRAME_SIZE(chn) (0x40001b0c + 0x40 * (chn)) // Set frame size (address increment), chn = 0..3, data type: x393_mcntrl_window_frame_sa_inc_t (wo)
#define X393_SENS_MCNTRL_TILED_FRAME_LAST(chn) (0x40001b10 + 0x40 * (chn)) // Set last frame number (number of frames in buffer minus 1), chn = 0..3, data type: x393_mcntrl_window_last_frame_num_t (wo)
#define X393_SENS_MCNTRL_TILED_FRAME_FULL_WIDTH(chn) (0x40001b14 + 0x40 * (chn)) // Set frame full(padded) width, chn = 0..3, data type: x393_mcntrl_window_full_width_t (wo)
#define X393_SENS_MCNTRL_TILED_WINDOW_WH(chn) (0x40001b18 + 0x40 * (chn)) // Set frame window size, chn = 0..3, data type: x393_mcntrl_window_width_height_t (wo)
#define X393_SENS_MCNTRL_TILED_WINDOW_X0Y0(chn) (0x40001b1c + 0x40 * (chn)) // Set frame position, chn = 0..3, data type: x393_mcntrl_window_left_top_t (wo)
#define X393_SENS_MCNTRL_TILED_STARTXY(chn) (0x40001b20 + 0x40 * (chn)) // Set startXY register, chn = 0..3, data type: x393_mcntrl_window_startx_starty_t (wo)
#define X393_SENS_MCNTRL_TILED_TILE_WHS(chn) (0x40001b24 + 0x40 * (chn)) // Set tile size/step (tiled mode only), chn = 0..3, data type: x393_mcntrl_window_tile_whs_t (wo)
// Write-only addresses to program memory channel for membridge, memory channel 1
#define X393_MEMBRIDGE_SCANLINE_MODE 0x40000480 // Set mode register (write last after other channel registers are set), data type: x393_mcntrl_mode_scan_t (wo)
#define X393_MEMBRIDGE_SCANLINE_STATUS_CNTRL 0x40000484 // Set status control register (status update mode), data type: x393_status_ctrl_t (rw)
#define X393_MEMBRIDGE_SCANLINE_STARTADDR 0x40000488 // Set frame start address, data type: x393_mcntrl_window_frame_sa_t (wo)
#define X393_MEMBRIDGE_SCANLINE_FRAME_SIZE 0x4000048c // Set frame size (address increment), data type: x393_mcntrl_window_frame_sa_inc_t (wo)
#define X393_MEMBRIDGE_SCANLINE_FRAME_LAST 0x40000490 // Set last frame number (number of frames in buffer minus 1), data type: x393_mcntrl_window_last_frame_num_t (wo)
#define X393_MEMBRIDGE_SCANLINE_FRAME_FULL_WIDTH 0x40000494 // Set frame full(padded) width, data type: x393_mcntrl_window_full_width_t (wo)
#define X393_MEMBRIDGE_SCANLINE_WINDOW_WH 0x40000498 // Set frame window size, data type: x393_mcntrl_window_width_height_t (wo)
#define X393_MEMBRIDGE_SCANLINE_WINDOW_X0Y0 0x4000049c // Set frame position, data type: x393_mcntrl_window_left_top_t (wo)
#define X393_MEMBRIDGE_SCANLINE_STARTXY 0x400004a0 // Set startXY register, data type: x393_mcntrl_window_startx_starty_t (wo)
#define X393_MEMBRIDGE_CTRL 0x40000800 // Issue membridge command, data type: x393_membridge_cmd_t (wo)
#define X393_MEMBRIDGE_STATUS_CNTRL 0x40000804 // Set membridge status control register, data type: x393_status_ctrl_t (rw)
#define X393_MEMBRIDGE_LO_ADDR64 0x40000808 // start address of the system memory range in QWORDs (4 LSBs==0), data type: u29_t (wo)
#define X393_MEMBRIDGE_SIZE64 0x4000080c // size of the system memory range in QWORDs (4 LSBs==0), rolls over, data type: u29_t (wo)
#define X393_MEMBRIDGE_START64 0x40000810 // start of transfer offset to system memory range in QWORDs (4 LSBs==0), data type: u29_t (wo)
#define X393_MEMBRIDGE_LEN64 0x40000814 // Full length of transfer in QWORDs, data type: u29_t (wo)
#define X393_MEMBRIDGE_WIDTH64 0x40000818 // Frame width in QWORDs (last xfer in each line may be partial), data type: u29_t (wo)
#define X393_MEMBRIDGE_MODE 0x4000081c // AXI cache mode, data type: x393_membridge_mode_t (wo)
// Write-only addresses to PS PIO (Software generated DDR3 memory access sequences)
#define X393_MCNTRL_PS_EN_RST 0x40000400 // Set PS PIO enable and reset, data type: x393_ps_pio_en_rst_t (wo)
#define X393_MCNTRL_PS_CMD 0x40000404 // Set PS PIO commands, data type: x393_ps_pio_cmd_t (wo)
#define X393_MCNTRL_PS_STATUS_CNTRL 0x40000408 // Set PS PIO status control register (status update mode), data type: x393_status_ctrl_t (rw)
// Write-only addresses to to program status report mode for memory controller
#define X393_MCONTR_PHY_STATUS_CNTRL 0x40000150 // Set status control register (status update mode), data type: x393_status_ctrl_t (rw)
#define X393_MCONTR_TOP_16BIT_STATUS_CNTRL 0x4000014c // Set status control register (status update mode), data type: x393_status_ctrl_t (rw)
// Write-only addresses to to program status report mode for test channels
#define X393_MCNTRL_TEST01_CHN2_STATUS_CNTRL 0x400003d4 // Set status control register (status update mode), data type: x393_status_ctrl_t (rw)
#define X393_MCNTRL_TEST01_CHN3_STATUS_CNTRL 0x400003dc // Set status control register (status update mode), data type: x393_status_ctrl_t (rw)
#define X393_MCNTRL_TEST01_CHN4_STATUS_CNTRL 0x400003e4 // Set status control register (status update mode), data type: x393_status_ctrl_t (rw)
// Write-only addresses for test channels commands
#define X393_MCNTRL_TEST01_CHN2_MODE 0x400003d0 // Set command for test01 channel 2, data type: x393_test01_mode_t (wo)
#define X393_MCNTRL_TEST01_CHN3_MODE 0x400003d8 // Set command for test01 channel 3, data type: x393_test01_mode_t (wo)
#define X393_MCNTRL_TEST01_CHN4_MODE 0x400003e0 // Set command for test01 channel 4, data type: x393_test01_mode_t (wo)
// Read-only addresses for status information
#define X393_MCONTR_PHY_STATUS 0x40002000 // Status register for MCNTRL PHY, data type: x393_status_mcntrl_phy_t (ro)
#define X393_MCONTR_TOP_STATUS 0x40002004 // Status register for MCNTRL requests, data type: x393_status_mcntrl_top_t (ro)
#define X393_MCNTRL_PS_STATUS 0x40002008 // Status register for MCNTRL software R/W, data type: x393_status_mcntrl_ps_t (ro)
#define X393_MCNTRL_CHN1_STATUS 0x40002010 // Status register for MCNTRL CHN1 (membridge), data type: x393_status_mcntrl_lintile_t (ro)
#define X393_MCNTRL_CHN3_STATUS 0x40002018 // Status register for MCNTRL CHN3 (scanline), data type: x393_status_mcntrl_lintile_t (ro)
#define X393_MCNTRL_CHN2_STATUS 0x40002014 // Status register for MCNTRL CHN2 (tiled), data type: x393_status_mcntrl_lintile_t (ro)
#define X393_MCNTRL_CHN4_STATUS 0x4000201c // Status register for MCNTRL CHN4 (tiled), data type: x393_status_mcntrl_lintile_t (ro)
#define X393_TEST01_CHN2_STATUS 0x400020f4 // Status register for test channel 2, data type: x393_status_mcntrl_testchn_t (ro)
#define X393_TEST01_CHN3_STATUS 0x400020f8 // Status register for test channel 3, data type: x393_status_mcntrl_testchn_t (ro)
#define X393_TEST01_CHN4_STATUS 0x400020fc // Status register for test channel 4, data type: x393_status_mcntrl_testchn_t (ro)
#define X393_MEMBRIDGE_STATUS 0x400020ec // Status register for membridge, data type: x393_status_membridge_t (ro)
// Write-only control of the sensor channels
#define X393_SENS_MODE(sens_num) (0x40001000 + 0x100 * (sens_num)) // Write sensor channel mode, sens_num = 0..3, data type: x393_sens_mode_t (wo)
#define X393_SENSI2C_CTRL(sens_num) (0x40001008 + 0x100 * (sens_num)) // Control sensor i2c, write i2c LUT, sens_num = 0..3, data type: x393_i2c_ctltbl_t (wo)
#define X393_SENSI2C_STATUS_CTRL(sens_num) (0x4000100c + 0x100 * (sens_num)) // Setup sensor i2c status report mode, sens_num = 0..3, data type: x393_status_ctrl_t (rw)
#define X393_SENS_SYNC_MULT(sens_num) (0x40001018 + 0x100 * (sens_num)) // Configure frames combining, sens_num = 0..3, data type: x393_sens_sync_mult_t (wo)
#define X393_SENS_SYNC_LATE(sens_num) (0x4000101c + 0x100 * (sens_num)) // Configure frame sync delay, sens_num = 0..3, data type: x393_sens_sync_late_t (wo)
#define X393_SENSIO_CTRL(sens_num) (0x40001020 + 0x100 * (sens_num)) // Configure sensor I/O port, sens_num = 0..3, data type: x393_sensio_ctl_t (wo)
#define X393_SENSIO_STATUS_CNTRL(sens_num) (0x40001024 + 0x100 * (sens_num)) // Set status control for SENSIO module, sens_num = 0..3, data type: x393_status_ctrl_t (rw)
#define X393_SENSIO_JTAG(sens_num) (0x40001028 + 0x100 * (sens_num)) // Programming interface for multiplexer FPGA (with X393_SENSIO_STATUS), sens_num = 0..3, data type: x393_sensio_jtag_t (wo)
#define X393_SENSIO_WIDTH(sens_num) (0x4000102c + 0x100 * (sens_num)) // Set sensor line in pixels (0 - use line sync from the sensor), sens_num = 0..3, data type: x393_sensio_width_t (rw)
#define X393_SENSIO_TIM0(sens_num) (0x40001030 + 0x100 * (sens_num)) // Sensor port i/o timing configuration, register 0, sens_num = 0..3, data type: x393_sensio_tim0_t (rw)
#define X393_SENSIO_TIM1(sens_num) (0x40001034 + 0x100 * (sens_num)) // Sensor port i/o timing configuration, register 1, sens_num = 0..3, data type: x393_sensio_tim1_t (rw)
#define X393_SENSIO_TIM2(sens_num) (0x40001038 + 0x100 * (sens_num)) // Sensor port i/o timing configuration, register 2, sens_num = 0..3, data type: x393_sensio_tim2_t (rw)
#define X393_SENSIO_TIM3(sens_num) (0x4000103c + 0x100 * (sens_num)) // Sensor port i/o timing configuration, register 3, sens_num = 0..3, data type: x393_sensio_tim3_t (rw)
// 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
#define X393_SENSI2C_ABS(sens_num,offset) (0x40001040)+ 0x40 * (sens_num)+ 0x1 * (offset)) // Write sensor i2c sequencer, sens_num = 0..3, offset = 0..15, data type: u32 (wo)
#define X393_SENSI2C_REL(sens_num,offset) (0x40001080)+ 0x40 * (sens_num)+ 0x1 * (offset)) // Write sensor i2c sequencer, sens_num = 0..3, offset = 0..15, data type: u32 (wo)
// Lens vignetting correction (for each sub-frame separately)
#define X393_LENS_HEIGHT0_M1(sens_num) (0x400010f0 + 0x100 * (sens_num)) // Subframe 0 height minus 1, sens_num = 0..3, data type: x393_lens_height_m1_t (rw)
#define X393_LENS_HEIGHT1_M1(sens_num) (0x400010f4 + 0x100 * (sens_num)) // Subframe 1 height minus 1, sens_num = 0..3, data type: x393_lens_height_m1_t (rw)
#define X393_LENS_HEIGHT2_M1(sens_num) (0x400010f8 + 0x100 * (sens_num)) // Subframe 2 height minus 1, sens_num = 0..3, data type: x393_lens_height_m1_t (rw)
#define X393_LENS_CORR_CNH_ADDR_DATA(sens_num) (0x400010fc + 0x100 * (sens_num)) // Combined address/data to write lens vignetting correction coefficients, sens_num = 0..3, data type: x393_lens_corr_t (wo)
// Lens vignetting coefficient addresses - use with x393_lens_corr_wo_t (X393_LENS_CORR_CNH_ADDR_DATA)
#define X393_LENS_AX 0x00000000 // Address of correction parameter Ax
#define X393_LENS_AX_MASK 0x000000f8 // Correction parameter Ax mask
#define X393_LENS_AY 0x00000008 // Address of correction parameter Ay
#define X393_LENS_AY_MASK 0x000000f8 // Correction parameter Ay mask
#define X393_LENS_C 0x00000010 // Address of correction parameter C
#define X393_LENS_C_MASK 0x000000f8 // Correction parameter C mask
#define X393_LENS_BX 0x00000020 // Address of correction parameter Bx
#define X393_LENS_BX_MASK 0x000000e0 // Correction parameter Bx mask
#define X393_LENS_BY 0x00000040 // Address of correction parameter By
#define X393_LENS_BY_MASK 0x000000e0 // Correction parameter By mask
#define X393_LENS_SCALE0 0x00000060 // Address of correction parameter scale0
#define X393_LENS_SCALE1 0x00000062 // Address of correction parameter scale1
#define X393_LENS_SCALE2 0x00000064 // Address of correction parameter scale2
#define X393_LENS_SCALE3 0x00000066 // Address of correction parameter scale3
#define X393_LENS_SCALES_MASK 0x000000f8 // Common mask for scales
#define X393_LENS_FAT0_IN 0x00000068 // Address of input fat zero parameter (to subtract from input)
#define X393_LENS_FAT0_IN_MASK 0x000000ff // Mask for fat zero input parameter
#define X393_LENS_FAT0_OUT 0x00000069 // Address of output fat zero parameter (to add to output)
#define X393_LENS_FAT0_OUT_MASK 0x000000ff // Mask for fat zero output parameters
#define X393_LENS_POST_SCALE 0x0000006a // Address of post scale (shift output) parameter
#define X393_LENS_POST_SCALE_MASK 0x000000ff // Mask for post scale parameter
// Sensor gamma conversion control (See Python code for examples of the table data generation)
#define X393_SENS_GAMMA_CTRL(sens_num) (0x400010e0 + 0x100 * (sens_num)) // Gamma module control, sens_num = 0..3, data type: x393_gamma_ctl_t (rw)
#define X393_SENS_GAMMA_TBL(sens_num) (0x400010e4 + 0x100 * (sens_num)) // Write sensor gamma table address/data (with autoincrement), sens_num = 0..3, data type: x393_gamma_tbl_t (wo)
#define X393_SENS_GAMMA_HEIGHT01M1(sens_num) (0x400010e8 + 0x100 * (sens_num)) // Gamma module subframes 0,1 heights minus 1, sens_num = 0..3, data type: x393_gamma_height01m1_t (rw)
#define X393_SENS_GAMMA_HEIGHT2M1(sens_num) (0x400010ec + 0x100 * (sens_num)) // Gamma module subframe 2 height minus 1, sens_num = 0..3, data type: x393_gamma_height2m1_t (rw)
// Windows for histogram subchannels
#define X393_HISTOGRAM_LT0(sens_num) (0x400010c0 + 0x100 * (sens_num)) // Specify histogram 0 left/top, sens_num = 0..3, data type: x393_hist_left_top_t (rw)
#define X393_HISTOGRAM_WH0(sens_num) (0x400010c4 + 0x100 * (sens_num)) // Specify histogram 0 width/height, sens_num = 0..3, data type: x393_hist_width_height_m1_t (rw)
#define X393_HISTOGRAM_LT1(sens_num) (0x400010c8 + 0x100 * (sens_num)) // Specify histogram 1 left/top, sens_num = 0..3, data type: x393_hist_left_top_t (rw)
#define X393_HISTOGRAM_WH1(sens_num) (0x400010cc + 0x100 * (sens_num)) // Specify histogram 1 width/height, sens_num = 0..3, data type: x393_hist_width_height_m1_t (rw)
#define X393_HISTOGRAM_LT2(sens_num) (0x400010d0 + 0x100 * (sens_num)) // Specify histogram 2 left/top, sens_num = 0..3, data type: x393_hist_left_top_t (rw)
#define X393_HISTOGRAM_WH2(sens_num) (0x400010d4 + 0x100 * (sens_num)) // Specify histogram 2 width/height, sens_num = 0..3, data type: x393_hist_width_height_m1_t (rw)
#define X393_HISTOGRAM_LT3(sens_num) (0x400010d8 + 0x100 * (sens_num)) // Specify histogram 3 left/top, sens_num = 0..3, data type: x393_hist_left_top_t (rw)
#define X393_HISTOGRAM_WH3(sens_num) (0x400010dc + 0x100 * (sens_num)) // Specify histogram 3 width/height, sens_num = 0..3, data type: x393_hist_width_height_m1_t (rw)
// DMA control for the histograms. Subchannel here is 4*sensor_port+ histogram_subchannel
#define X393_HIST_SAXI_MODE 0x40001440 // Histogram DMA operation mode, data type: x393_hist_saxi_mode_t (rw)
#define X393_HIST_SAXI_ADDR(subchannel) (0x40001400 + 0x4 * (subchannel)) // Histogram DMA addresses (in 4096 byte pages), subchannel = 0..15, data type: x393_hist_saxi_addr_t (rw)
// Read-only addresses for sensors status information
#define X393_SENSI2C_STATUS(sens_num) (0x40002080 + 0x8 * (sens_num)) // Status of the sensors i2c, sens_num = 0..3, data type: x393_status_sens_i2c_t (ro)
#define X393_SENSIO_STATUS(sens_num) (0x40002084 + 0x8 * (sens_num)) // Status of the sensor ports I/O pins, sens_num = 0..3, data type: x393_status_sens_io_t (ro)
// Compressor bitfields values
#define X393_CMPRS_CBIT_RUN_RST 0x00000000 // Reset compressor, stop immediately
#define X393_CMPRS_CBIT_RUN_DISABLE 0x00000001 // Disable compression of the new frames, finish any already started
#define X393_CMPRS_CBIT_RUN_STANDALONE 0x00000002 // Enable compressor, compress single frame from memory (async)
#define X393_CMPRS_CBIT_RUN_ENABLE 0x00000003 // Enable synchronous compression mode
#define X393_CMPRS_CBIT_CMODE_JPEG18 0x00000000 // Color 4:2:0 3x3 de-bayer core
#define X393_CMPRS_CBIT_CMODE_MONO6 0x00000001 // Mono 4:2:0 (6 blocks)
#define X393_CMPRS_CBIT_CMODE_JP46 0x00000002 // jp4, 6 blocks, original
#define X393_CMPRS_CBIT_CMODE_JP46DC 0x00000003 // jp4, 6 blocks, DC-improved
#define X393_CMPRS_CBIT_CMODE_JPEG20 0x00000004 // Color 4:2:0 with 5x5 de-bayer (not implemented)
#define X393_CMPRS_CBIT_CMODE_JP4 0x00000005 // jp4, 4 blocks
#define X393_CMPRS_CBIT_CMODE_JP4DC 0x00000006 // jp4, 4 blocks, DC-improved
#define X393_CMPRS_CBIT_CMODE_JP4DIFF 0x00000007 // jp4, 4 blocks, differential
#define X393_CMPRS_CBIT_CMODE_JP4DIFFHDR 0x00000008 // jp4, 4 blocks, differential, hdr
#define X393_CMPRS_CBIT_CMODE_JP4DIFFDIV2 0x00000009 // jp4, 4 blocks, differential, divide by 2
#define X393_CMPRS_CBIT_CMODE_JP4DIFFHDRDIV2 0x0000000a // jp4, 4 blocks, differential, hdr,divide by 2
#define X393_CMPRS_CBIT_CMODE_MONO1 0x0000000b // Mono JPEG (not yet implemented)
#define X393_CMPRS_CBIT_CMODE_MONO4 0x0000000e // Mono, 4 blocks (2x2 macroblocks)
#define X393_CMPRS_CBIT_CMODE_JPEG18 0x00000000 // Color 4:2:0
#define X393_CMPRS_CBIT_FRAMES_SINGLE 0x00000000 // Use single-frame buffer
#define X393_CMPRS_CBIT_FRAMES_MULTI 0x00000001 // Use multi-frame buffer
// Compressor control
#define X393_CMPRS_CONTROL_REG(cmprs_chn) (0x40001800 + 0x40 * (cmprs_chn)) // Program compressor channel operation mode, cmprs_chn = 0..3, data type: x393_cmprs_mode_t (wo)
#define X393_CMPRS_STATUS(cmprs_chn) (0x40001804 + 0x40 * (cmprs_chn)) // Setup compressor status report mode, cmprs_chn = 0..3, data type: x393_status_ctrl_t (rw)
#define X393_CMPRS_FORMAT(cmprs_chn) (0x40001808 + 0x40 * (cmprs_chn)) // Compressor frame format, cmprs_chn = 0..3, data type: x393_cmprs_frame_format_t (rw)
#define X393_CMPRS_COLOR_SATURATION(cmprs_chn) (0x4000180c + 0x40 * (cmprs_chn)) // Compressor color saturation, cmprs_chn = 0..3, data type: x393_cmprs_colorsat_t (rw)
#define X393_CMPRS_CORING_MODE(cmprs_chn) (0x40001810 + 0x40 * (cmprs_chn)) // Select coring mode, cmprs_chn = 0..3, data type: x393_cmprs_coring_mode_t (rw)
#define X393_CMPRS_INTERRUPTS(cmprs_chn) (0x40001814 + 0x40 * (cmprs_chn)) // Compressor interrupts control (1 - clear, 2 - disable, 3 - enable), cmprs_chn = 0..3, data type: x393_cmprs_interrupts_t (wo)
// 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
#define X393_TABLE_QUANTIZATION_TYPE 0x00000000 // Quantization table type
#define X393_TABLE_CORING_TYPE 0x00000001 // Coring table type
#define X393_TABLE_FOCUS_TYPE 0x00000002 // Focus table type
#define X393_TABLE_HUFFMAN_TYPE 0x00000003 // Huffman table type
// Compressor tables control
#define X393_CMPRS_TABLES_DATA(cmprs_chn) (0x40001818 + 0x40 * (cmprs_chn)) // Compressor tables data, cmprs_chn = 0..3, data type: u32 (wo)
#define X393_CMPRS_TABLES_ADDRESS(cmprs_chn) (0x4000181c + 0x40 * (cmprs_chn)) // Compressor tables type/address, cmprs_chn = 0..3, data type: x393_cmprs_table_addr_t (wo)
// Compressor channel status)
#define X393_CMPRS_STATUS(chn) (0x40002040 + 0x4 * (chn)) // Status of the compressor channel (incl. interrupt, chn = 0..3, data type: x393_cmprs_status_t (ro)
#define X393_CMPRS_HIFREQ(chn) (0x40002050 + 0x4 * (chn)) // Focus helper high-frequency amount, chn = 0..3, data type: u32 (ro)
// 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
#define X393_AFIMUX0_EN 0x40001900 // AFI MUX 0 global/port run/pause control, data type: x393_afimux_en_t (wo)
#define X393_AFIMUX0_RST 0x40001904 // AFI MUX 0 per-port resets, data type: x393_afimux_rst_t (rw)
#define X393_AFIMUX0_REPORT_MODE 0x40001908 // AFI MUX 0 readout pointer report mode, data type: x393_afimux_report_t (wo)
#define X393_AFIMUX0_STATUS_CONTROL 0x40001910 // AFI MUX 0 status report mode, data type: x393_status_ctrl_t (rw)
#define X393_AFIMUX0_SA(afi_port) (0x40001920 + 0x4 * (afi_port)) // AFI MUX 0 DMA buffer start address in 32-byte blocks, afi_port = 0..3, data type: x393_afimux_sa_t (rw)
#define X393_AFIMUX0_LEN(afi_port) (0x40001930 + 0x4 * (afi_port)) // AFI MUX 0 DMA buffer length in 32-byte blocks, afi_port = 0..3, data type: x393_afimux_len_t (rw)
// Same for the second AXI HP channel (not currently used)
#define X393_AFIMUX1_EN 0x40001940 // AFI MUX 1 global/port run/pause control, data type: x393_afimux_en_t (wo)
#define X393_AFIMUX1_RST 0x40001944 // AFI MUX 1 per-port resets, data type: x393_afimux_rst_t (rw)
#define X393_AFIMUX1_REPORT_MODE 0x40001948 // AFI MUX 1 readout pointer report mode, data type: x393_afimux_report_t (wo)
#define X393_AFIMUX1_STATUS_CONTROL 0x40001950 // AFI MUX 1 status report mode, data type: x393_status_ctrl_t (rw)
#define X393_AFIMUX1_SA(afi_port) (0x40001960 + 0x4 * (afi_port)) // AFI MUX 1 DMA buffer start address in 32-byte blocks, afi_port = 0..3, data type: x393_afimux_sa_t (rw)
#define X393_AFIMUX1_LEN(afi_port) (0x40001970 + 0x4 * (afi_port)) // AFI MUX 1 DMA buffer length in 32-byte blocks, afi_port = 0..3, data type: x393_afimux_len_t (rw)
// Read-only sensors status information (pointer offset and last sequence number)
#define X393_AFIMUX0_STATUS(afi_port) (0x40002060 + 0x4 * (afi_port)) // Status of the AFI MUX 0 (including image pointer), afi_port = 0..3, data type: x393_afimux_status_t (ro)
#define X393_AFIMUX1_STATUS(afi_port) (0x40002070 + 0x4 * (afi_port)) // Status of the AFI MUX 1 (including image pointer), afi_port = 0..3, data type: x393_afimux_status_t (ro)
//
// 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
#define X393_GPIO_SET_PINS 0x40001c00 // State of the GPIO pins and seq. number, data type: x393_gpio_set_pins_t (wo)
#define X393_GPIO_STATUS_CONTROL 0x40001c04 // GPIO status control mode, data type: x393_status_ctrl_t (rw)
// Read-only GPIO pins state
#define X393_GPIO_STATUS 0x400020c0 // State of the GPIO pins and seq. number, data type: x393_gpio_status_t (ro)
// RTC control
#define X393_RTC_USEC 0x40001c10 // RTC microseconds, data type: x393_rtc_usec_t (rw)
#define X393_RTC_SEC_SET 0x40001c14 // RTC seconds and set clock, data type: x393_rtc_sec_t (rw)
#define X393_RTC_CORR 0x40001c18 // RTC correction (+/- 1/256 full scale), data type: x393_rtc_corr_t (rw)
#define X393_RTC_SET_STATUS 0x40001c1c // RTC status control mode, write makes a snapshot to be read out, data type: x393_status_ctrl_t (rw)
// Read-only RTC state
#define X393_RTC_STATUS 0x400020c4 // RTC status reg, data type: x393_rtc_status_t (ro)
#define X393_RTC_STATUS_SEC 0x400020c8 // RTC snapshot seconds, data type: x393_rtc_sec_t (ro)
#define X393_RTC_STATUS_USEC 0x400020cc // RTC snapshot microseconds, data type: x393_rtc_usec_t (ro)
// CAMSYNC control
#define X393_CAMSYNC_MODE 0x40001c20 // CAMSYNC mode, data type: x393_camsync_mode_t (wo)
#define X393_CAMSYNC_TRIG_SRC 0x40001c24 // CAMSYNC trigger source, data type: x393_camsync_io_t (wo)
#define X393_CAMSYNC_TRIG_DST 0x40001c28 // CAMSYNC trigger destination, data type: x393_camsync_io_t (wo)
// 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
#define X393_CAMSYNC_TRIG_PERIOD 0x40001c2c // CAMSYNC trigger period, data type: u32 (rw)
#define X393_CAMSYNC_TRIG_DELAY(sens_chn) (0x40001c30 + 0x4 * (sens_chn)) // CAMSYNC trigger delay, sens_chn = 0..3, data type: u32 (rw)
// Command sequencer control
// Controller is programmed through 32 locations. Each registers but the control require two writes:
// 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
#define X393_CMDFRAMESEQ_CTRL(sens_chn) (0x40001e7c + 0x80 * (sens_chn)) // CMDFRAMESEQ control register, sens_chn = 0..3, data type: x393_cmdframeseq_mode_t (wo)
#define X393_CMDFRAMESEQ_ABS(sens_chn,offset) (0x40001e00)+ 0x20 * (sens_chn)+ 0x1 * (offset)) // CMDFRAMESEQ absolute frame address/command, sens_chn = 0..3, offset = 0..15, data type: u32 (wo)
#define X393_CMDFRAMESEQ_REL(sens_chn,offset) (0x40001e40)+ 0x20 * (sens_chn)+ 0x1 * (offset)) // CMDFRAMESEQ relative frame address/command, sens_chn = 0..3, offset = 0..14, data type: u32 (wo)
// Command sequencer multiplexer, provides current frame number for each sensor channel and interrupt status/interrupt masks for them.
// Interrupts and interrupt masks are controlled through channel CMDFRAMESEQ module
#define X393_CMDSEQMUX_STATUS_CTRL 0x40001c08 // CMDSEQMUX status control mode (status provides current frame numbers), data type: x393_status_ctrl_t (rw)
#define X393_CMDSEQMUX_STATUS 0x400020e0 // CMDSEQMUX status data (frame numbers and interrupts, data type: x393_cmdseqmux_status_t (ro)
// Event logger
// Event logger configuration/data is writtent to the module ising two 32-bit register locations : data and address.
// Address consists of 2 parts - 2-bit page (configuration, imu, gps, message) and a 5-bit sub-address autoincremented when writing data.
// Register pages:
#define X393_LOGGER_PAGE_CONF 0x00000000 // Logger configuration page
#define X393_LOGGER_PAGE_IMU 0x00000003 // Logger IMU parameters page
#define X393_LOGGER_PAGE_GPS 0x00000001 // Logger GPS parameters page
#define X393_LOGGER_PAGE_MSG 0x00000002 // Logger MSG (odometer) parameters page
// Register configuration addresses (with X393_LOGGER_PAGE_CONF):
#define X393_LOGGER_PERIOD 0x00000000 // IMU period (in SPI clocks, high word 0xffff - use IMU ready)
#define X393_LOGGER_BIT_DURATION 0x00000001 // IMU SPI bit duration (in mclk == 50 ns periods?)
#define X393_LOGGER_BIT_HALF_PERIOD 0x00000002 // Logger rs232 half bit period (in mclk == 50 ns periods?)
#define X393_LOGGER_CONFIG 0x00000003 // Logger IMU parameters page
#define X393_LOGGER_STATUS_CTRL 0x40001c88 // Logger status configuration (to report sample number), data type: x393_status_ctrl_t (rw)
#define X393_LOGGER_DATA 0x40001c80 // Logger register write data, data type: x393_logger_data_t (wo)
#define X393_LOGGER_ADDRESS 0x40001c84 // Logger register write page/address, data type: x393_logger_address_t (wo)
#define X393_LOGGER_STATUS 0x400020e4 // Logger status data (sequence number), data type: x393_logger_status_t (ro)
// MULT SAXI DMA engine control. Of 4 channels only one (number 0) is currently used - for the event logger
#define X393_MULT_SAXI_STATUS_CTRL 0x40001ce0 // MULT_SAXI status control mode (status provides current DWORD pointer), data type: x393_status_ctrl_t (rw)
#define X393_MULT_SAXI_BUF_ADDRESS(chn) (0x40001cc0 + 0x8 * (chn)) // MULT_SAXI buffer start address in DWORDS, chn = 0..3, data type: x393_mult_saxi_al_t (wo)
#define X393_MULT_SAXI_BUF_LEN(chn) (0x40001cc4 + 0x8 * (chn)) // MULT_SAXI buffer length in DWORDS, chn = 0..3, data type: x393_mult_saxi_al_t (wo)
#define X393_MULT_SAXI_STATUS(chn) (0x400020d0 + 0x4 * (chn)) // MULT_SAXI current DWORD pointer, chn = 0..3, data type: x393_mult_saxi_al_t (ro)
// MULTI_CLK - global clock generation PLLs. Interface provided for debugging, no interaction is needed for normal operation
#define X393_MULTICLK_STATUS_CTRL 0x40001ca4 // MULTI_CLK status generation (do not use or do not set auto), data type: x393_status_ctrl_t (rw)
#define X393_MULTICLK_CTRL 0x40001ca0 // MULTI_CLK reset and power down control, data type: x393_multiclk_ctl_t (rw)
#define X393_MULTICLK_STATUS 0x400020e8 // MULTI_CLK lock and toggle state, data type: x393_multiclk_status_t (ro)
// 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.
#define X393_DEBUG_STATUS_CTRL 0x40001c48 // Debug ring status generation - set to auto(3) if used, data type: x393_status_ctrl_t (rw)
#define X393_DEBUG_LOAD 0x40001c44 // Debug ring copy shift register to/from tested modules
#define X393_DEBUG_SHIFT 0x40001c40 // Debug ring shift ring by 32 bits, data type: u32 (wo)
#define X393_DEBUG_STATUS 0x400023f0 // Debug read status (watch sequence number), data type: x393_debug_status_t (ro)
#define X393_DEBUG_READ 0x400023f4 // Debug read DWORD form ring register, data type: u32 (ro)
// Write-only addresses to program memory channel 3 (test channel)
#define X393_MCNTRL_CHN3_SCANLINE_MODE 0x400004c0 // Set mode register (write last after other channel registers are set), data type: x393_mcntrl_mode_scan_t (wo)
#define X393_MCNTRL_CHN3_SCANLINE_STATUS_CNTRL 0x400004c4 // Set status control register (status update mode), data type: x393_status_ctrl_t (rw)
#define X393_MCNTRL_CHN3_SCANLINE_STARTADDR 0x400004c8 // Set frame start address, data type: x393_mcntrl_window_frame_sa_t (wo)
#define X393_MCNTRL_CHN3_SCANLINE_FRAME_SIZE 0x400004cc // Set frame size (address increment), data type: x393_mcntrl_window_frame_sa_inc_t (wo)
#define X393_MCNTRL_CHN3_SCANLINE_FRAME_LAST 0x400004d0 // Set last frame number (number of frames in buffer minus 1), data type: x393_mcntrl_window_last_frame_num_t (wo)
#define X393_MCNTRL_CHN3_SCANLINE_FRAME_FULL_WIDTH 0x400004d4 // Set frame full(padded) width, data type: x393_mcntrl_window_full_width_t (wo)
#define X393_MCNTRL_CHN3_SCANLINE_WINDOW_WH 0x400004d8 // Set frame window size, data type: x393_mcntrl_window_width_height_t (wo)
#define X393_MCNTRL_CHN3_SCANLINE_WINDOW_X0Y0 0x400004dc // Set frame position, data type: x393_mcntrl_window_left_top_t (wo)
#define X393_MCNTRL_CHN3_SCANLINE_STARTXY 0x400004e0 // Set startXY register, data type: x393_mcntrl_window_startx_starty_t (wo)
// Write-only addresses to program memory channel 2 (test channel)
#define X393_MCNTRL_CHN2_TILED_MODE 0x40000500 // Set mode register (write last after other channel registers are set), data type: x393_mcntrl_mode_scan_t (wo)
#define X393_MCNTRL_CHN2_TILED_STATUS_CNTRL 0x40000504 // Set status control register (status update mode), data type: x393_status_ctrl_t (rw)
#define X393_MCNTRL_CHN2_TILED_STARTADDR 0x40000508 // Set frame start address, data type: x393_mcntrl_window_frame_sa_t (wo)
#define X393_MCNTRL_CHN2_TILED_FRAME_SIZE 0x4000050c // Set frame size (address increment), data type: x393_mcntrl_window_frame_sa_inc_t (wo)
#define X393_MCNTRL_CHN2_TILED_FRAME_LAST 0x40000510 // Set last frame number (number of frames in buffer minus 1), data type: x393_mcntrl_window_last_frame_num_t (wo)
#define X393_MCNTRL_CHN2_TILED_FRAME_FULL_WIDTH 0x40000514 // Set frame full(padded) width, data type: x393_mcntrl_window_full_width_t (wo)
#define X393_MCNTRL_CHN2_TILED_WINDOW_WH 0x40000518 // Set frame window size, data type: x393_mcntrl_window_width_height_t (wo)
#define X393_MCNTRL_CHN2_TILED_WINDOW_X0Y0 0x4000051c // Set frame position, data type: x393_mcntrl_window_left_top_t (wo)
#define X393_MCNTRL_CHN2_TILED_STARTXY 0x40000520 // Set startXY register, data type: x393_mcntrl_window_startx_starty_t (wo)
#define X393_MCNTRL_CHN2_TILED_TILE_WHS 0x40000524 // Set tile size/step (tiled mode only), data type: x393_mcntrl_window_tile_whs_t (wo)
// Write-only addresses to program memory channel 4 (test channel)
#define X393_MCNTRL_CHN4_TILED_MODE 0x40000540 // Set mode register (write last after other channel registers are set), data type: x393_mcntrl_mode_scan_t (wo)
#define X393_MCNTRL_CHN4_TILED_STATUS_CNTRL 0x40000544 // Set status control register (status update mode), data type: x393_status_ctrl_t (rw)
#define X393_MCNTRL_CHN4_TILED_STARTADDR 0x40000548 // Set frame start address, data type: x393_mcntrl_window_frame_sa_t (wo)
#define X393_MCNTRL_CHN4_TILED_FRAME_SIZE 0x4000054c // Set frame size (address increment), data type: x393_mcntrl_window_frame_sa_inc_t (wo)
#define X393_MCNTRL_CHN4_TILED_FRAME_LAST 0x40000550 // Set last frame number (number of frames in buffer minus 1), data type: x393_mcntrl_window_last_frame_num_t (wo)
#define X393_MCNTRL_CHN4_TILED_FRAME_FULL_WIDTH 0x40000554 // Set frame full(padded) width, data type: x393_mcntrl_window_full_width_t (wo)
#define X393_MCNTRL_CHN4_TILED_WINDOW_WH 0x40000558 // Set frame window size, data type: x393_mcntrl_window_width_height_t (wo)
#define X393_MCNTRL_CHN4_TILED_WINDOW_X0Y0 0x4000055c // Set frame position, data type: x393_mcntrl_window_left_top_t (wo)
#define X393_MCNTRL_CHN4_TILED_STARTXY 0x40000560 // Set startXY register, data type: x393_mcntrl_window_startx_starty_t (wo)
#define X393_MCNTRL_CHN4_TILED_TILE_WHS 0x40000564 // Set tile size/step (tiled mode only), data type: x393_mcntrl_window_tile_whs_t (wo)
This source diff could not be displayed because it is too large. You can view the blob instead.
/*******************************************************************************
* File: x393_types.h
* Date: 2016-04-06
* Author: auto-generated file, see x393_export_c.py
* Description: typedef definitions for the x393 hardware registers
*******************************************************************************/
// Status generation control
typedef union {
struct {
u32 seq_num: 6; // [ 5: 0] (0) 6-bit sequence number to be used with the next status response
u32 mode: 2; // [ 7: 6] (3) Status report mode: 0 - disable, 1 - single, 2 - auto, keep sequence number, 3 - auto, inc. seq. number
u32 :24;
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_status_ctrl_t;
// Memory channel operation mode
typedef union {
struct {
u32 enable: 1; // [ 0] (1) enable requests from this channel ( 0 will let current to finish, but not raise want/need)
u32 chn_nreset: 1; // [ 1] (1) 0: immediately reset all the internal circuitry
u32 write_mem: 1; // [ 2] (0) 0 - read from memory, 1 - write to memory
u32 extra_pages: 2; // [ 4: 3] (0) 2-bit number of extra pages that need to stay (not to be overwritten) in the buffer
u32 keep_open: 1; // [ 5] (0) for 8 or less rows - do not close page between accesses (not used in scanline mode)
u32 byte32: 1; // [ 6] (1) 32-byte columns (0 - 16-byte), not used in scanline mode
u32 : 1;
u32 reset_frame: 1; // [ 8] (0) reset frame number
u32 single: 1; // [ 9] (0) run single frame
u32 repetitive: 1; // [ 10] (1) run repetitive frames
u32 disable_need: 1; // [ 11] (0) disable 'need' generation, only 'want' (compressor channels)
u32 skip_too_late: 1; // [ 12] (0) Skip over missed blocks to preserve frame structure (increment pointers)
u32 :19;
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_mcntrl_mode_scan_t;
// Memory channel window tile size/step (tiled only)
typedef union {
struct {
u32 tile_width: 6; // [ 5: 0] (2) tile width in 8-bursts (16 bytes)
u32 : 2;
u32 tile_height: 6; // [13: 8] (0x12) tile height in lines (0 means 64 lines)
u32 : 2;
u32 vert_step: 8; // [23:16] (0x10) Tile vertical step to control tile overlap
u32 : 8;
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_mcntrl_window_tile_whs_t;
// Memory channel window size
typedef union {
struct {
u32 width:13; // [12: 0] (0) 13-bit window width - in 8*16=128 bit bursts
u32 : 3;
u32 height:16; // [31:16] (0) 16-bit window height in scan lines
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_mcntrl_window_width_height_t;
// Memory channel window position
typedef union {
struct {
u32 left:13; // [12: 0] (0) 13-bit window left margin in 8-bursts (16 bytes)
u32 : 3;
u32 top:16; // [31:16] (0) 16-bit window top margin in scan lines
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_mcntrl_window_left_top_t;
// Memory channel scan start (debug feature)
typedef union {
struct {
u32 start_x:13; // [12: 0] (0) 13-bit window start X relative to window left margin (debug feature, set = 0)
u32 : 3;
u32 start_y:16; // [31:16] (0) 16-bit window start Y relative to window top margin (debug feature, set = 0)
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_mcntrl_window_startx_starty_t;
// Memory channel window full (padded) width
typedef union {
struct {
u32 full_width:13; // [12: 0] (0) 13-bit Padded line length (8-row increment), in 8-bursts (16 bytes)
u32 :19;
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_mcntrl_window_full_width_t;
// Memory channel last frame number in a buffer (number of frames minus 1)
typedef union {
struct {
u32 last_frame_num:16; // [15: 0] (0) 16-bit number of the last frame in a buffer (1 for a 2-frame ping-pong one)
u32 :16;
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_mcntrl_window_last_frame_num_t;
// Memory channel frame start address increment (for next frame in a buffer)
typedef union {
struct {
u32 frame_sa_inc:22; // [21: 0] (0) 22-bit frame start address increment (3 CA LSBs==0. BA==0)
u32 :10;
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_mcntrl_window_frame_sa_inc_t;
// Memory channel frame start address for the first frame in a buffer
typedef union {
struct {
u32 frame_sa:22; // [21: 0] (0) 22-bit frame start address (3 CA LSBs==0. BA==0)
u32 :10;
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_mcntrl_window_frame_sa_t;
// PS PIO (software-programmed DDR3) access sequences enable and reset
typedef union {
struct {
u32 nrst: 1; // [ 0] (1) Active-low reset for programmed DDR3 memory sequences
u32 en: 1; // [ 1] (1) Enable PS_PIO channel. Only influences request for arbitration, started transactions will finish if disabled
u32 :30;
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_ps_pio_en_rst_t;
// PS PIO (software-programmed DDR3) access sequences control
typedef union {
struct {
u32 seq_addr:10; // [ 9: 0] (0) Sequence start address
u32 page: 2; // [11:10] (0) Buffer page number
u32 urgent: 1; // [ 12] (0) high priority request (only for competition with other channels, will not pass in this FIFO)
u32 chn: 1; // [ 13] (0) channel buffer to use: 0 - memory read, 1 - memory write
u32 wait_complete: 1; // [ 14] (0) Do not request a new transaction from the scheduler until previous memory transaction is finished
u32 :17;
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_ps_pio_cmd_t;
// x393 generic status register
typedef union {
struct {
u32 status24:24; // [23: 0] (0) 24-bit status payload ([25:2] in Verilog
u32 status2: 2; // [25:24] (0) 2-bit status payload (2 LSB in Verilog)
u32 seq_num: 6; // [31:26] (0) Sequence number
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_status_t;
// Memory PHY status
typedef union {
struct {
u32 ps_out: 8; // [ 7: 0] (0) Current MMCM phase shift
u32 run_busy: 1; // [ 8] (0) Controller sequence in progress
u32 locked_pll: 1; // [ 9] (0) PLL is locked
u32 locked_mmcm: 1; // [ 10] (0) MMCM is locked
u32 dci_ready: 1; // [ 11] (0) DCI calibration is ready
u32 dly_ready: 1; // [ 12] (0) I/O delays calibration is ready
u32 :11;
u32 ps_rdy: 1; // [ 24] (0) Phase change is done
u32 locked: 1; // [ 25] (0) Both PLL and MMCM are locked
u32 seq_num: 6; // [31:26] (0) Sequence number
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_status_mcntrl_phy_t;
// Memory controller requests status
typedef union {
struct {
u32 chn_want:16; // [15: 0] (0) Bit mask of the channels that request memory access
u32 : 8;
u32 want_some: 1; // [ 24] (0) At least one channel requests memory access (normal priority)
u32 need_some: 1; // [ 25] (0) At least one channel requests urgent memory access (high priority)
u32 seq_num: 6; // [31:26] (0) Sequence number
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_status_mcntrl_top_t;
// Memory software access status
typedef union {
struct {
u32 :24;
u32 cmd_half_full: 1; // [ 24] (0) MCNTRL software access pending commands FIFO is half full
u32 cmd_nempty_busy: 1; // [ 25] (0) MCNTRL software access pending commands FIFO is not empty or command is running
u32 seq_num: 6; // [31:26] (0) Sequence number
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_status_mcntrl_ps_t;
// Memory test channels access status
typedef union {
struct {
u32 :24;
u32 busy: 1; // [ 24] (0) Channel is busy (started and some memory accesses are pending)
u32 frame_finished: 1; // [ 25] (0) Channel completed all memory accesses
u32 seq_num: 6; // [31:26] (0) Sequence number
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_status_mcntrl_lintile_t;
// Memory test channels status
typedef union {
struct {
u32 line_unfinished:16; // [15: 0] (0) Current unfinished frame line
u32 page: 4; // [19:16] (0) Current page number read/written through a channel (low bits)
u32 : 4;
u32 frame_busy: 1; // [ 24] (0) Channel is busy (started and some memory accesses are pending)
u32 frame_finished: 1; // [ 25] (0) Channel completed all memory accesses
u32 seq_num: 6; // [31:26] (0) Sequence number
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_status_mcntrl_testchn_t;
// Membridge channel status
typedef union {
struct {
u32 wresp_conf: 8; // [ 7: 0] (0) Number of 64-bit words confirmed through axi b channel (low bits)
u32 axi_arw_requested: 8; // [15: 8] (0) Number of 64-bit words to be read/written over axi queued to AR/AW channels (low bits)
u32 : 8;
u32 busy: 1; // [ 24] (0) Membridge operation in progress
u32 done: 1; // [ 25] (0) Membridge operation finished
u32 seq_num: 6; // [31:26] (0) Sequence number
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_status_membridge_t;
// Sensor/multiplexer I/O pins status
typedef union {
struct {
u32 ps_out: 8; // [ 7: 0] (0) Sensor MMCM current phase
u32 ps_rdy: 1; // [ 8] (0) Sensor MMCM phase ready
u32 xfpgadone: 1; // [ 9] (0) Multiplexer FPGA DONE output
u32 clkfb_pxd_stopped_mmcm: 1; // [ 10] (0) Sensor MMCM feedback clock stopped
u32 clkin_pxd_stopped_mmcm: 1; // [ 11] (0) Sensor MMCM input clock stopped
u32 locked_pxd_mmcm: 1; // [ 12] (0) Sensor MMCM locked
u32 hact_alive: 1; // [ 13] (0) HACT signal from the sensor (or internal) is toggling (N/A for HiSPI
u32 hact_ext_alive: 1; // [ 14] (0) HACT signal from the sensor is toggling (N/A for HiSPI)
u32 vact_alive: 1; // [ 15] (0) VACT signal from the sensor is toggling (N/A for HiSPI)
u32 : 8;
u32 senspgmin: 1; // [ 24] (0) senspgm pin state
u32 xfpgatdo: 1; // [ 25] (0) Multiplexer FPGA TDO output
u32 seq_num: 6; // [31:26] (0) Sequence number
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_status_sens_io_t;
// Sensor/multiplexer i2c status
typedef union {
struct {
u32 i2c_fifo_dout: 8; // [ 7: 0] (0) I2c byte read from the device through FIFO
u32 i2c_fifo_nempty: 1; // [ 8] (0) I2C read FIFO has data
u32 i2c_fifo_lsb: 1; // [ 9] (0) I2C FIFO byte counter (odd/even bytes)
u32 busy: 1; // [ 10] (0) I2C sequencer busy
u32 alive_fs: 1; // [ 11] (0) Sensor generated frame sync since last status update
u32 frame_num: 4; // [15:12] (0) I2C sequencer frame number
u32 req_clr: 1; // [ 16] (0) Request for clearing fifo_wp (delay frame sync if previous is not yet sent out)
u32 reset_on: 1; // [ 17] (0) Reset in progress
u32 : 6;
u32 scl_in: 1; // [ 24] (0) SCL pin state
u32 sda_in: 1; // [ 25] (0) SDA pin state
u32 seq_num: 6; // [31:26] (0) Sequence number
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_status_sens_i2c_t;
// Command bits for test01 module (test frame memory accesses)
typedef union {
struct {
u32 frame_start: 1; // [ 0] (0) start frame command
u32 next_page: 1; // [ 1] (0) Next page command
u32 suspend: 1; // [ 2] (0) Suspend command
u32 :29;
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_test01_mode_t;
// Command for membridge
typedef union {
struct {
u32 enable: 1; // [ 0] (0) enable membridge
u32 start_reset: 2; // [ 2: 1] (0) 1 - start (from current address), 3 - start from reset address
u32 :29;
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_membridge_cmd_t;
// Cache mode for membridge
typedef union {
struct {
u32 axi_cache: 4; // [ 3: 0] (3) AXI CACHE value (ignored by Zynq)
u32 debug_cache: 1; // [ 4] (0) 0 - normal operation, 1 debug (replace data)
u32 :27;
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_membridge_mode_t;
// Address in 64-bit words
typedef union {
struct {
u32 addr64:29; // [28: 0] (0) Address/length in 64-bit words (<<3 to get byte address
u32 : 3;
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} u29_t;
// I2C contol/table data
typedef union {
struct {
u32 tbl_addr: 8; // [ 7: 0] (0) Address/length in 64-bit words (<<3 to get byte address)
u32 :20;
u32 tbl_mode: 2; // [29:28] (3) Should be 3 to select table address write mode
u32 : 2;
};
struct {
u32 rah: 8; // [ 7: 0] (0) High byte of the i2c register address
u32 rnw: 1; // [ 8] (0) Read/not write i2c register, should be 0 here
u32 sa: 7; // [15: 9] (0) Slave address in write mode
u32 nbwr: 4; // [19:16] (0) Number of bytes to write (1..10)
u32 dly: 8; // [27:20] (0) Bit delay - number of mclk periods in 1/4 of the SCL period
u32 /*tbl_mode*/: 2; // [29:28] (2) Should be 2 to select table data write mode
u32 : 2;
};
struct {
u32 /*rah*/: 8; // [ 7: 0] (0) High byte of the i2c register address
u32 /*rnw*/: 1; // [ 8] (0) Read/not write i2c register, should be 1 here
u32 : 7;
u32 nbrd: 3; // [18:16] (0) Number of bytes to read (1..18, 0 means '8')
u32 nabrd: 1; // [ 19] (0) Number of address bytes for read (0 - one byte, 1 - two bytes)
u32 /*dly*/: 8; // [27:20] (0) Bit delay - number of mclk periods in 1/4 of the SCL period
u32 /*tbl_mode*/: 2; // [29:28] (2) Should be 2 to select table data write mode
u32 : 2;
};
struct {
u32 sda_drive_high: 1; // [ 0] (0) Actively drive SDA high during second half of SCL==1 (valid with drive_ctl)
u32 sda_release: 1; // [ 1] (0) Release SDA early if next bit ==1 (valid with drive_ctl)
u32 drive_ctl: 1; // [ 2] (0) 0 - nop, 1 - set sda_release and sda_drive_high
u32 next_fifo_rd: 1; // [ 3] (0) Advance I2C read FIFO pointer
u32 soft_scl: 2; // [ 5: 4] (0) Control SCL pin (when stopped): 0 - nop, 1 - low, 2 - high (driven), 3 - float
u32 soft_sda: 2; // [ 7: 6] (0) Control SDA pin (when stopped): 0 - nop, 1 - low, 2 - high (driven), 3 - float
u32 : 4;
u32 cmd_run: 2; // [13:12] (0) Sequencer run/stop control: 0,1 - nop, 2 - stop, 3 - run
u32 reset: 1; // [ 14] (0) Sequencer reset all FIFO (takes 16 clock pulses), also - stops i2c until run command
u32 :13;
u32 /*tbl_mode*/: 2; // [29:28] (0) Should be 0 to select controls
u32 : 2;
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_i2c_ctltbl_t;
// Write sensor channel mode register
typedef union {
struct {
u32 hist_en: 4; // [ 3: 0] (0xf) Enable subchannel histogram modules (may be less than 4)
u32 hist_nrst: 4; // [ 7: 4] (0xf) Reset off for histograms subchannels (may be less than 4)
u32 chn_en: 1; // [ 8] (1) Enable this sensor channel
u32 bit16: 1; // [ 9] (0) 0 - 8 bpp mode, 1 - 16 bpp (bypass gamma). Gamma-processed data is still used for histograms
u32 :22;
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_sens_mode_t;
// Write number of sensor frames to combine into one virtual (linescan mode)
typedef union {
struct {
u32 mult_frames:16; // [15: 0] (0) Number of frames to combine into one minus 1 (0 - single,1 - two frames...)
u32 :16;
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_sens_sync_mult_t;
// Write sensor number of lines to delay frame sync
typedef union {
struct {
u32 mult_frames:16; // [15: 0] (0) Number of lines to delay late frame sync
u32 :16;
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_sens_sync_late_t;
// Configure memory controller priorities
typedef union {
struct {
u32 priority:16; // [15: 0] (0) Channel priority (the larger the higher)
u32 :16;
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_arbite_pri_t;
// Enable/disable memory controller channels
typedef union {
struct {
u32 chn_en:16; // [15: 0] (0) Enabled memory channels
u32 :16;
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_mcntr_chn_en_t;
// DQS and DQM patterns (DQM - 0, DQS 0xaa or 0x55)
typedef union {
struct {
u32 dqs_patt: 8; // [ 7: 0] (0xaa) DQS pattern: 0xaa/0x55
u32 dqm_patt: 8; // [15: 8] (0) DQM pattern: 0x0
u32 :16;
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_mcntr_dqs_dqm_patt_t;
// DQ and DQS tristate control when turning on and off
typedef union {
struct {
u32 dq_tri_first: 4; // [ 3: 0] (3) DQ tristate start (0x3,0x7,0xf); early, nominal, late
u32 dq_tri_last: 4; // [ 7: 4] (0xe) DQ tristate end (0xf,0xe,0xc); early, nominal, late
u32 dqs_tri_first: 4; // [11: 8] (1) DQS tristate start (0x1,0x3,0x7); early, nominal, late
u32 dqs_tri_last: 4; // [15:12] (0xc) DQS tristate end (0xe,0xc,0x8); early, nominal, late
u32 :16;
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_mcntr_dqs_dqm_tri_t;
// DDR3 memory controller I/O delay
typedef union {
struct {
u32 dly: 8; // [ 7: 0] (0) 8-bit delay value: 5MSBs(0..31) and 3LSBs(0..4)
u32 :24;
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_dly_t;
// Extra delay in mclk (fDDR/2) cycles) to data write buffer
typedef union {
struct {
u32 wbuf_dly: 4; // [ 3: 0] (9) Extra delay in mclk (fDDR/2) cycles) to data write buffer
u32 :28;
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_wbuf_dly_t;
// Control for the gamma-conversion module
typedef union {
struct {
u32 bayer: 2; // [ 1: 0] (0) Bayer color shift (pixel to gamma table)
u32 page: 1; // [ 2] (0) Table page (only available if SENS_GAMMA_BUFFER in Verilog)
u32 en: 1; // [ 3] (1) Enable module
u32 repet: 1; // [ 4] (1) Repetitive (normal) mode. Set 0 for testing of the single-frame mode
u32 trig: 1; // [ 5] (0) Single trigger used when repetitive mode is off (self clearing bit)
u32 :26;
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_gamma_ctl_t;
// Write gamma table address/data
typedef union {
struct {
u32 addr: 8; // [ 7: 0] (0) Start address in a gamma page (normally 0)
u32 color: 2; // [ 9: 8] (0) Color channel
u32 sub_chn: 2; // [11:10] (0) Sensor sub-channel (multiplexed to the same port)
u32 : 8;
u32 a_n_d: 1; // [ 20] (1) Address/not data, should be set to 1 here
u32 :11;
};
struct {
u32 base:10; // [ 9: 0] (0) Knee point value (to be interpolated between)
char diff: 7; // [16:10] (0) Difference to next (signed, -64..+63)
u32 diff_scale: 1; // [ 17] (0) Difference scale: 0 - keep diff, 1- multiply diff by 16
u32 :14;
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_gamma_tbl_t;
// Heights of the first two subchannels frames
typedef union {
struct {
u32 height0m1:16; // [15: 0] (0) Height of subchannel 0 frame minus 1
u32 height1m1:16; // [31:16] (0) Height of subchannel 1 frame minus 1
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_gamma_height01m1_t;
// Height of the third subchannel frame
typedef union {
struct {
u32 height2m1:16; // [15: 0] (0) Height of subchannel 2 frame minus 1
u32 :16;
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_gamma_height2m1_t;
// Sensor port I/O control
typedef union {
struct {
u32 mrst: 1; // [ 0] (0) MRST signal level to the sensor (0 - low(active), 1 - high (inactive)
u32 mrst_set: 1; // [ 1] (0) when set to 1, MRST is set to the 'mrst' field value
u32 arst: 1; // [ 2] (0) ARST signal to the sensor
u32 arst_set: 1; // [ 3] (0) ARST set to the 'arst' field
u32 aro: 1; // [ 4] (0) ARO signal to the sensor
u32 aro_set: 1; // [ 5] (0) ARO set to the 'aro' field
u32 mmcm_rst: 1; // [ 6] (0) MMCM (for sensor clock) reset signal
u32 mmcm_rst_set: 1; // [ 7] (0) MMCM reset set to 'mmcm_rst' field
u32 ext_clk: 1; // [ 8] (0) MMCM clock input: 0: clock to the sensor, 1 - clock from the sensor
u32 ext_clk_set: 1; // [ 9] (0) Set MMCM clock input to 'ext_clk' field
u32 set_dly: 1; // [ 10] (0) Set all pre-programmed delays to the sensor port input delays
u32 : 1;
u32 quadrants: 6; // [17:12] (1) 90-degree shifts for data [1:0], hact [3:2] and vact [5:4]
u32 : 2;
u32 quadrants_set: 1; // [ 20] (0) Set 'quadrants' values
u32 :11;
};
struct {
u32 /*mrst*/: 1; // [ 0] (0) MRST signal level to the sensor (0 - low(active), 1 - high (inactive)
u32 /*mrst_set*/: 1; // [ 1] (0) when set to 1, MRST is set to the 'mrst' field value
u32 /*arst*/: 1; // [ 2] (0) ARST signal to the sensor
u32 /*arst_set*/: 1; // [ 3] (0) ARST set to the 'arst' field
u32 /*aro*/: 1; // [ 4] (0) ARO signal to the sensor
u32 /*aro_set*/: 1; // [ 5] (0) ARO set to the 'aro' field
u32 /*mmcm_rst*/: 1; // [ 6] (0) MMCM (for sensor clock) reset signal
u32 /*mmcm_rst_set*/: 1; // [ 7] (0) MMCM reset set to 'mmcm_rst' field
u32 ign_embed: 1; // [ 8] (0) Ignore embedded data (non-image pixel lines
u32 ign_embed_set: 1; // [ 9] (0) Set mode to 'ign_embed' field
u32 /*set_dly*/: 1; // [ 10] (0) Set all pre-programmed delays to the sensor port input delays
u32 : 1;
u32 gp0: 1; // [ 12] (0) GP0 multipurpose signal to the sensor
u32 gp0_set: 1; // [ 13] (0) Set GP0 to 'gp0' value
u32 gp1: 1; // [ 14] (0) GP1 multipurpose signal to the sensor
u32 gp1_set: 1; // [ 15] (0) Set GP1 to 'gp1' value
u32 :16;
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_sensio_ctl_t;
// Programming interface for multiplexer FPGA
typedef union {
struct {
u32 tdi: 1; // [ 0] (0) JTAG TDI level
u32 tdi_set: 1; // [ 1] (0) JTAG TDI set to 'tdi' field
u32 tms: 1; // [ 2] (0) JTAG TMS level
u32 tms_set: 1; // [ 3] (0) JTAG TMS set to 'tms' field
u32 tck: 1; // [ 4] (0) JTAG TCK level
u32 tck_set: 1; // [ 5] (0) JTAG TCK set to 'tck' field
u32 prog: 1; // [ 6] (0) Sensor port PROG level
u32 prog_set: 1; // [ 7] (0) Sensor port PROG set to 'prog' field
u32 pgmen: 1; // [ 8] (0) Sensor port PGMEN level
u32 pgmen_set: 1; // [ 9] (0) Sensor port PGMEN set to 'pgmen' field
u32 :22;
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_sensio_jtag_t;
// Sensor i/o timing register 0 (different meanings for different sensor types)
typedef union {
struct {
u32 pxd0: 8; // [ 7: 0] (0) PXD0 input delay (3 LSB not used)
u32 pxd1: 8; // [15: 8] (0) PXD1 input delay (3 LSB not used)
u32 pxd2: 8; // [23:16] (0) PXD2 input delay (3 LSB not used)
u32 pxd3: 8; // [31:24] (0) PXD3 input delay (3 LSB not used)
};
struct {
u32 fifo_lag: 4; // [ 3: 0] (7) FIFO delay to start output
u32 :28;
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_sensio_tim0_t;
// Sensor i/o timing register 1 (different meanings for different sensor types)
typedef union {
struct {
u32 pxd4: 8; // [ 7: 0] (0) PXD4 input delay (3 LSB not used)
u32 pxd5: 8; // [15: 8] (0) PXD5 input delay (3 LSB not used)
u32 pxd6: 8; // [23:16] (0) PXD6 input delay (3 LSB not used)
u32 pxd7: 8; // [31:24] (0) PXD7 input delay (3 LSB not used)
};
struct {
u32 phys_lane0: 2; // [ 1: 0] (1) Physical lane for logical lane 0
u32 phys_lane1: 2; // [ 3: 2] (2) Physical lane for logical lane 1
u32 phys_lane2: 2; // [ 5: 4] (3) Physical lane for logical lane 2
u32 phys_lane3: 2; // [ 7: 6] (0) Physical lane for logical lane 3
u32 :24;
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_sensio_tim1_t;
// Sensor i/o timing register 2 (different meanings for different sensor types)
typedef union {
struct {
u32 pxd8: 8; // [ 7: 0] (0) PXD8 input delay (3 LSB not used)
u32 pxd9: 8; // [15: 8] (0) PXD9 input delay (3 LSB not used)
u32 pxd10: 8; // [23:16] (0) PXD10 input delay (3 LSB not used)
u32 pxd11: 8; // [31:24] (0) PXD11 input delay (3 LSB not used)
};
struct {
u32 dly_lane0: 8; // [ 7: 0] (0) lane 0 (phys) input delay (3 LSB not used)
u32 dly_lane1: 8; // [15: 8] (0) lane 1 (phys) input delay (3 LSB not used)
u32 dly_lane2: 8; // [23:16] (0) lane 2 (phys) input delay (3 LSB not used)
u32 dly_lane3: 8; // [31:24] (0) lane 3 (phys) input delay (3 LSB not used)
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_sensio_tim2_t;
// Sensor i/o timing register 3 (different meanings for different sensor types)
typedef union {
struct {
u32 hact: 8; // [ 7: 0] (0) HACT input delay (3 LSB not used)
u32 vact: 8; // [15: 8] (0) VACT input delay (3 LSB not used)
u32 bpf: 8; // [23:16] (0) BPF (clock from sensor) input delay (3 LSB not used)
u32 phase_p: 8; // [31:24] (0) MMCM phase
};
struct {
u32 phase_h: 8; // [ 7: 0] (0) MMCM phase
u32 :24;
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_sensio_tim3_t;
// Set sensor frame width (0 - use received)
typedef union {
struct {
u32 sensor_width:16; // [15: 0] (0) Sensor frame width (0 - use line sync signals from the sensor)
u32 :16;
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_sensio_width_t;
// Lens vignetting parameter (write address first, then data that may overlap som address bits)
typedef union {
struct {
u32 :16;
u32 addr: 8; // [23:16] (0) Lens correction address, should be written first (overlaps with data)
u32 sub_chn: 2; // [25:24] (0) Sensor subchannel
u32 : 6;
};
struct {
u32 ax:19; // [18: 0] (0x20000) Coefficient Ax
u32 :13;
};
struct {
u32 ay:19; // [18: 0] (0x20000) Coefficient Ay
u32 :13;
};
struct {
u32 bx:21; // [20: 0] (0x180000) Coefficient Bx
u32 :11;
};
struct {
u32 by:21; // [20: 0] (0x180000) Coefficient By
u32 :11;
};
struct {
u32 c:19; // [18: 0] (0x8000) Coefficient C
u32 :13;
};
struct {
u32 scale:17; // [16: 0] (0x8000) Scale (4 per-color values)
u32 :15;
};
struct {
u32 fatzero_in:16; // [15: 0] (0) 'Fat zero' on the input (subtract from the input)
u32 :16;
};
struct {
u32 fatzero_out:16; // [15: 0] (0) 'Fat zero' on the output (add to the result)
u32 :16;
};
struct {
u32 post_scale: 4; // [ 3: 0] (1) Shift result (bits)
u32 :28;
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_lens_corr_t;
// Height of the subchannel frame for vignetting correction
typedef union {
struct {
u32 height_m1:16; // [15: 0] (0) Height of subframe minus 1
u32 :16;
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_lens_height_m1_t;
// Histogram window left/top margins
typedef union {
struct {
u32 left:16; // [15: 0] (0) Histogram window left margin
u32 top:16; // [31:16] (0) Histogram window top margin
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_hist_left_top_t;
// Histogram window width and height minus 1 (0 use full)
typedef union {
struct {
u32 width_m1:16; // [15: 0] (0) Width of the histogram window minus 1. If 0 - use frame right margin (end of HACT)
u32 height_m1:16; // [31:16] (0) Height of he histogram window minus 1. If 0 - use frame bottom margin (end of VACT)
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_hist_width_height_m1_t;
// Histograms DMA mode
typedef union {
struct {
u32 en: 1; // [ 0] (1) Enable histograms DMA
u32 nrst: 1; // [ 1] (1) 0 - reset histograms DMA
u32 confirm: 1; // [ 2] (1) 1 - wait for confirmation that histogram was written to the system memory
u32 : 1;
u32 cache: 4; // [ 7: 4] (3) AXI cache mode (normal - 3), ignored by Zynq?
u32 :24;
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_hist_saxi_mode_t;
// Histograms DMA addresses
typedef union {
struct {
u32 page:20; // [19: 0] (0) Start address of the subchannel histogram (in pages = 4096 bytes
u32 :12;
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_hist_saxi_addr_t;
// Compressor mode control
typedef union {
struct {
u32 run: 2; // [ 1: 0] (0) Run mode
u32 run_set: 1; // [ 2] (0) Set 'run'
u32 qbank: 3; // [ 5: 3] (0) Quantization table bank
u32 qbank_set: 1; // [ 6] (0) Set 'qbank'
u32 dcsub: 1; // [ 7] (0) Subtract DC enable
u32 dcsub_set: 1; // [ 8] (0) Set 'qbank'
u32 cmode: 4; // [12: 9] (0) Color format
u32 cmode_set: 1; // [ 13] (0) Set 'cmode'
u32 multiframe: 1; // [ 14] (0) Multi/single frame mode
u32 multiframe_set: 1; // [ 15] (0) Set 'multiframe'
u32 : 2;
u32 bayer: 2; // [19:18] (0) Bayer shift
u32 bayer_set: 1; // [ 20] (0) Set 'bayer'
u32 focus: 2; // [22:21] (0) Focus mode
u32 focus_set: 1; // [ 23] (0) Set 'focus'
u32 : 8;
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_cmprs_mode_t;
// Compressor coring mode (table number)
typedef union {
struct {
u32 coring_table: 3; // [ 2: 0] (0) Select coring table pair number
u32 :29;
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_cmprs_coring_mode_t;
// Compressor color saturation
typedef union {
struct {
u32 colorsat_blue:10; // [ 9: 0] (0x120) Color saturation for blue (0x90 - 100%)
u32 : 2;
u32 colorsat_red:10; // [21:12] (0x16c) Color saturation for red (0xb6 - 100%)
u32 :10;
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_cmprs_colorsat_t;
// Compressor frame format
typedef union {
struct {
u32 num_macro_cols_m1:13; // [12: 0] (0) Number of macroblock colums minus 1
u32 num_macro_rows_m1:13; // [25:13] (0) Number of macroblock rows minus 1
u32 left_margin: 5; // [30:26] (0) Left margin of the first pixel (0..31) for 32-pixel wide colums in memory access
u32 : 1;
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_cmprs_frame_format_t;
// Compressor interrupts control
typedef union {
struct {
u32 interrupt_cmd: 2; // [ 1: 0] (0) 0: nop, 1: clear interrupt status, 2: disable interrupt, 3: enable interrupt
u32 :30;
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_cmprs_interrupts_t;
// Compressor tables load control
typedef union {
struct {
u32 addr32:24; // [23: 0] (0) Table address to start writing to (autoincremented) for DWORDs
u32 type: 2; // [25:24] (0) 0: quantization, 1: coring, 2: focus, 3: huffman
u32 : 6;
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_cmprs_table_addr_t;
// Compressor channel status
typedef union {
struct {
u32 is: 1; // [ 0] (0) Compressor channel interrupt status
u32 im: 1; // [ 1] (0) Compressor channel interrupt mask
u32 reading_frame: 1; // [ 2] (0) Compressor channel is reading frame from memory (debug feature)
u32 stuffer_running: 1; // [ 3] (0) Compressor channel bit stuffer is running (debug feature)
u32 flushing_fifo: 1; // [ 4] (0) Compressor channel is flushing FIFO (debug feature)
u32 :21;
u32 seq_num: 6; // [31:26] (0) Status sequence number
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_cmprs_status_t;
// Compressor DMA buffer address (in 32-byte blocks)
typedef union {
struct {
u32 sa256:27; // [26: 0] (0) System memory buffer start in multiples of 32 bytes (256 bits)
u32 : 5;
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_afimux_sa_t;
// Compressor DMA buffer length (in 32-byte blocks)
typedef union {
struct {
u32 len256:27; // [26: 0] (0) System memory buffer length in multiples of 32 bytes (256 bits)
u32 : 5;
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_afimux_len_t;
// Compressor DMA channels reset
typedef union {
struct {
u32 rst0: 1; // [ 0] (0) AXI HPx sub-channel0 reset (0 - normal operation, 1 - reset)
u32 rst1: 1; // [ 1] (0) AXI HPx sub-channel0 reset (0 - normal operation, 1 - reset)
u32 rst2: 1; // [ 2] (0) AXI HPx sub-channel0 reset (0 - normal operation, 1 - reset)
u32 rst3: 1; // [ 3] (0) AXI HPx sub-channel0 reset (0 - normal operation, 1 - reset)
u32 :28;
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_afimux_rst_t;
// Compressor DMA enable (global and channels)
typedef union {
struct {
u32 en0: 1; // [ 0] (0) AXI HPx sub-channel0 enable value to set (0 - pause, 1 - run)
u32 en0_set: 1; // [ 1] (0) 0 - nop, 1 - set en0
u32 en1: 1; // [ 2] (0) AXI HPx sub-channel1 enable value to set (0 - pause, 1 - run)
u32 en1_set: 1; // [ 3] (0) 0 - nop, 1 - set en1
u32 en2: 1; // [ 4] (0) AXI HPx sub-channel2 enable value to set (0 - pause, 1 - run)
u32 en2_set: 1; // [ 5] (0) 0 - nop, 1 - set en2
u32 en3: 1; // [ 6] (0) AXI HPx sub-channel3 enable value to set (0 - pause, 1 - run)
u32 en3_set: 1; // [ 7] (0) 0 - nop, 1 - set en3
u32 en: 1; // [ 8] (0) AXI HPx global enable value to set (0 - pause, 1 - run)
u32 en_set: 1; // [ 9] (0) 0 - nop, 1 - set en
u32 :22;
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_afimux_en_t;
// Compressor DMA report mode
typedef union {
struct {
u32 mode0: 2; // [ 1: 0] (0) channel0 report mode: 0 - EOF int, 1 - EOF confirmed, 2 - CP (current), 3 - CP confirmed
u32 mode0_set: 1; // [ 2] (0) 0 - nop, 1 - set mode0
u32 : 1;
u32 mode1: 2; // [ 5: 4] (0) channel0 report mode: 0 - EOF int, 1 - EOF confirmed, 2 - CP (current), 3 - CP confirmed
u32 mode1_set: 1; // [ 6] (0) 0 - nop, 1 - set mode0
u32 : 1;
u32 mode2: 2; // [ 9: 8] (0) channel0 report mode: 0 - EOF int, 1 - EOF confirmed, 2 - CP (current), 3 - CP confirmed
u32 mode2_set: 1; // [ 10] (0) 0 - nop, 1 - set mode0
u32 : 1;
u32 mode3: 2; // [13:12] (0) channel0 report mode: 0 - EOF int, 1 - EOF confirmed, 2 - CP (current), 3 - CP confirmed
u32 mode3_set: 1; // [ 14] (0) 0 - nop, 1 - set mode0
u32 :17;
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_afimux_report_t;
// Compressor DMA status
typedef union {
struct {
u32 offset256:26; // [25: 0] (0) AFI MUX current/EOF pointer offset in 32-byte blocks
u32 seq_num: 6; // [31:26] (0) Status sequence number
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_afimux_status_t;
// GPIO output control
typedef union {
struct {
u32 pin0: 2; // [ 1: 0] (0) Output control for pin 0: 0 - nop, 1 - set low, 2 - set high, 3 - tristate
u32 pin1: 2; // [ 3: 2] (0) Output control for pin 1: 0 - nop, 1 - set low, 2 - set high, 3 - tristate
u32 pin2: 2; // [ 5: 4] (0) Output control for pin 2: 0 - nop, 1 - set low, 2 - set high, 3 - tristate
u32 pin3: 2; // [ 7: 6] (0) Output control for pin 3: 0 - nop, 1 - set low, 2 - set high, 3 - tristate
u32 pin4: 2; // [ 9: 8] (0) Output control for pin 4: 0 - nop, 1 - set low, 2 - set high, 3 - tristate
u32 pin5: 2; // [11:10] (0) Output control for pin 5: 0 - nop, 1 - set low, 2 - set high, 3 - tristate
u32 pin6: 2; // [13:12] (0) Output control for pin 6: 0 - nop, 1 - set low, 2 - set high, 3 - tristate
u32 pin7: 2; // [15:14] (0) Output control for pin 7: 0 - nop, 1 - set low, 2 - set high, 3 - tristate
u32 pin8: 2; // [17:16] (0) Output control for pin 8: 0 - nop, 1 - set low, 2 - set high, 3 - tristate
u32 pin9: 2; // [19:18] (0) Output control for pin 0: 0 - nop, 1 - set low, 2 - set high, 3 - tristate
u32 : 4;
u32 soft: 2; // [25:24] (0) Enable pin software control: 0,1 - nop, 2 - disab;e, 3 - enable
u32 chn_a: 2; // [27:26] (0) Enable A channel (camsync): 0,1 - nop, 2 - disab;e, 3 - enable
u32 chn_b: 2; // [29:28] (0) Enable B channel (reserved): 0,1 - nop, 2 - disab;e, 3 - enable
u32 chn_c: 2; // [31:30] (0) Enable C channel (logger): 0,1 - nop, 2 - disab;e, 3 - enable
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_gpio_set_pins_t;
// GPIO pins status
typedef union {
struct {
u32 pin0: 1; // [ 0] (0) GPIO pin 0 state
u32 pin1: 1; // [ 1] (0) GPIO pin 0 state
u32 pin2: 1; // [ 2] (0) GPIO pin 0 state
u32 pin3: 1; // [ 3] (0) GPIO pin 0 state
u32 pin4: 1; // [ 4] (0) GPIO pin 0 state
u32 pin5: 1; // [ 5] (0) GPIO pin 0 state
u32 pin6: 1; // [ 6] (0) GPIO pin 0 state
u32 pin7: 1; // [ 7] (0) GPIO pin 0 state
u32 pin8: 1; // [ 8] (0) GPIO pin 0 state
u32 pin9: 1; // [ 9] (0) GPIO pin 0 state
u32 :16;
u32 seq_num: 6; // [31:26] (0) Status sequence number
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_gpio_status_t;
// RTC seconds
typedef union {
struct {
u32 sec:32; // [31: 0] (0) RTC seconds
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_rtc_sec_t;
// RTC microseconds
typedef union {
struct {
u32 usec:20; // [19: 0] (0) RTC microseconds
u32 :12;
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_rtc_usec_t;
// RTC correction
typedef union {
struct {
short corr:16; // [15: 0] (0) RTC correction, +/1 1/256 full scale
u32 :16;
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_rtc_corr_t;
// RTC status
typedef union {
struct {
u32 :24;
u32 alt_snap: 1; // [ 24] (0) alternates 0/1 each time RTC timer makes a snapshot
u32 : 1;
u32 seq_num: 6; // [31:26] (0) Status sequence number
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_rtc_status_t;
// CAMSYNC I/O configuration
typedef union {
struct {
u32 line0: 2; // [ 1: 0] (1) line 0 mode: 0 - inactive, 1 - keep (nop), 2 - active low, 3 - active high
u32 line1: 2; // [ 3: 2] (1) line 1 mode: 0 - inactive, 1 - keep (nop), 2 - active low, 3 - active high
u32 line2: 2; // [ 5: 4] (1) line 2 mode: 0 - inactive, 1 - keep (nop), 2 - active low, 3 - active high
u32 line3: 2; // [ 7: 6] (1) line 3 mode: 0 - inactive, 1 - keep (nop), 2 - active low, 3 - active high
u32 line4: 2; // [ 9: 8] (1) line 4 mode: 0 - inactive, 1 - keep (nop), 2 - active low, 3 - active high
u32 line5: 2; // [11:10] (1) line 5 mode: 0 - inactive, 1 - keep (nop), 2 - active low, 3 - active high
u32 line6: 2; // [13:12] (1) line 6 mode: 0 - inactive, 1 - keep (nop), 2 - active low, 3 - active high
u32 line7: 2; // [15:14] (1) line 7 mode: 0 - inactive, 1 - keep (nop), 2 - active low, 3 - active high
u32 line8: 2; // [17:16] (1) line 8 mode: 0 - inactive, 1 - keep (nop), 2 - active low, 3 - active high
u32 line9: 2; // [19:18] (1) line 9 mode: 0 - inactive, 1 - keep (nop), 2 - active low, 3 - active high
u32 :12;
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_camsync_io_t;
// CAMSYNC mode
typedef union {
struct {
u32 en: 1; // [ 0] (1) Enable CAMSYNC module
u32 en_snd: 1; // [ 1] (1) Enable sending timestamps (valid with 'en_snd_set')
u32 en_snd_set: 1; // [ 2] (0) Set 'en_snd'
u32 ext: 1; // [ 3] (1) Use external (received) timestamps, if available. O - use local timestamps
u32 ext_set: 1; // [ 4] (0) Set 'ext'
u32 trig: 1; // [ 5] (1) Sensor triggered mode (0 - free running sensor)
u32 trig_set: 1; // [ 6] (0) Set 'trig'
u32 master_chn: 2; // [ 8: 7] (0) master sensor channel (zero delay in internal trigger mode, delay used for flash output)
u32 master_chn_set: 1; // [ 9] (0) Set 'master_chn'
u32 ts_chns: 4; // [13:10] (1) Channels to generate timestmp messages (bit mask)
u32 ts_chns_set: 1; // [ 14] (0) Set 'ts_chns'
u32 :17;
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_camsync_mode_t;
// CMDFRAMESEQ mode
typedef union {
struct {
u32 interrupt_cmd: 2; // [ 1: 0] (0) Interrupt command: 0-nop, 1 - clear is, 2 - disable, 3 - enable
u32 :10;
u32 run_cmd: 2; // [13:12] (0) Run command: 0,1 - nop, 2 - stop, 3 - run
u32 reset: 1; // [ 14] (0) 1 - reset, 0 - normal operation
u32 :17;
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_cmdframeseq_mode_t;
// CMDFRAMESEQ mode
typedef union {
struct {
u32 frame_num0: 4; // [ 3: 0] (0) Frame number for sensor 0
u32 frame_num1: 4; // [ 7: 4] (0) Frame number for sensor 0
u32 frame_num2: 4; // [11: 8] (0) Frame number for sensor 0
u32 frame_num3: 4; // [15:12] (0) Frame number for sensor 0
u32 is: 4; // [19:16] (0) Interrupt status: 1 bit per sensor channel
u32 im: 4; // [23:20] (0) Interrupt enable: 1 bit per sensor channel
u32 : 2;
u32 seq_num: 6; // [31:26] (0) Status sequence number
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_cmdseqmux_status_t;
// Event logger status
typedef union {
struct {
u32 sample:24; // [23: 0] (0) Logger sample number
u32 : 2;
u32 seq_num: 6; // [31:26] (0) Status sequence number
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_logger_status_t;
// Event logger register address
typedef union {
struct {
u32 addr: 5; // [ 4: 0] (0) Register address (autoincrements in 32 DWORDs (page) range
u32 page: 2; // [ 6: 5] (0) Register page: configuration: 0, IMU: 3, GPS: 1, MSG: 2
u32 :25;
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_logger_address_t;
// Event logger register data
typedef union {
struct {
u32 imu_slot: 2; // [ 1: 0] (0) IMU slot
u32 imu_set: 1; // [ 2] (0) Set 'imu_slot'
u32 gps_slot: 2; // [ 4: 3] (0) GPS slot
u32 gps_invert: 1; // [ 5] (0) GPS inpert 1pps signal
u32 gps_ext: 1; // [ 6] (0) GPS sync to 1 pps signal (0 - sync to serial message)
u32 gps_set: 1; // [ 7] (0) Set 'gps_*' fields
u32 msg_input: 4; // [11: 8] (0) MSG pin: GPIO pin number to accept external signal (0xf - disable)
u32 msg_invert: 1; // [ 12] (0) MSG input polarity - 0 - active high, 1 - active low
u32 msg_set: 1; // [ 13] (0) Set 'msg_*' fields
u32 log_sync: 4; // [17:14] (0) Log frame sync events (bit per sensor channel)
u32 log_sync_set: 1; // [ 18] (0) Set 'log_sync' fields
u32 :13;
};
struct {
u32 data:32; // [31: 0] (0) Other logger register data (context-dependent)
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_logger_data_t;
// MULT_SAXI DMA addresses/lengths in 32-bit DWORDS
typedef union {
struct {
u32 addr32:30; // [29: 0] (0) SAXI sddress/length in DWORDs
u32 : 2;
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_mult_saxi_al_t;
// MULTICLK reset/power down controls
typedef union {
struct {
u32 rst_clk0: 1; // [ 0] (0) Reset PLL for xclk(240MHz), hclk(150MHz)
u32 rst_clk1: 1; // [ 1] (0) Reset PLL for pclk (sensors, from ffclk0)
u32 rst_clk2: 1; // [ 2] (0) reserved
u32 rst_clk3: 1; // [ 3] (0) reserved
u32 pwrdwnclk0: 1; // [ 4] (0) Power down PLL for xclk(240MHz), hclk(150MHz)
u32 pwrdwn_clk1: 1; // [ 5] (0) Power down for pclk (sensors, from ffclk0)
u32 pwrdwn_clk2: 1; // [ 6] (0) reserved
u32 pwrdwn_clk3: 1; // [ 7] (0) reserved
u32 rst_memclk: 1; // [ 8] (0) reset memclk (external in for memory) toggle FF
u32 rst_ffclk0: 1; // [ 9] (0) reset ffclk0 (external in for sensors) toggle FF
u32 rst_ffclk1: 1; // [ 10] (0) reset ffclk1 (exteranl in, not yet used) toggle FF
u32 :21;
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_multiclk_ctl_t;
// MULTICLK status
typedef union {
struct {
u32 locked0: 1; // [ 0] (0) Locked PLL for xclk(240MHz), hclk(150MHz)
u32 locked1: 1; // [ 1] (0) Locked PLL for pclk (sensors, from ffclk0)
u32 locked2: 1; // [ 2] (0) ==1, reserved
u32 locked3: 1; // [ 3] (0) ==1, reserved
u32 tgl_memclk: 1; // [ 4] (0) memclk (external in for memory) toggle FF
u32 tgl_ffclk0: 1; // [ 5] (0) ffclk0 (external in for sensors) toggle FF
u32 tgl_ffclk1: 1; // [ 6] (0) ffclk1 (exteranl in, not yet used) toggle FF
u32 :17;
u32 idelay_rdy: 1; // [ 24] (0) idelay_ctrl_rdy (juct to prevent from optimization)
u32 : 1;
u32 seq_num: 6; // [31:26] (0) Status sequence number
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_multiclk_status_t;
// DEBUG status
typedef union {
struct {
u32 :24;
u32 tgl: 1; // [ 24] (0) Toggles for each DWORD received
u32 : 1;
u32 seq_num: 6; // [31:26] (0) Status sequence number
};
struct {
u32 d32:32; // [31: 0] (0) cast to u32
};
} x393_debug_status_t;
...@@ -301,7 +301,7 @@ static int make_group (struct device *dev, const char * name, int port_mask, mod ...@@ -301,7 +301,7 @@ static int make_group (struct device *dev, const char * name, int port_mask, mod
{ {
int retval=-1; int retval=-1;
int port,index=0,num_regs; int port,index=0,num_regs;
struct attribute **pattrs; /* array of pointers to attibutes */ struct attribute **pattrs; /* array of pointers to attributes */
struct device_attribute *dev_attrs; struct device_attribute *dev_attrs;
struct attribute_group *attr_group; struct attribute_group *attr_group;
for (port=0,num_regs=1;port<MAX_PORTS;port++) if (port_mask & (1<<port)) num_regs++; /* 1 extra - used for all ports */ for (port=0,num_regs=1;port<MAX_PORTS;port++) if (port_mask & (1<<port)) num_regs++; /* 1 extra - used for all ports */
......
...@@ -58,6 +58,11 @@ ...@@ -58,6 +58,11 @@
#define FPGA_SJTAG_BOUNDARY_MINOR 6 // read/write boundary pins of the sensor board FPGA #define FPGA_SJTAG_BOUNDARY_MINOR 6 // read/write boundary pins of the sensor board FPGA
#define FPGA_AJTAG_BOUNDARY_MINOR 7 // read/write boundary pins of the aux board FPGA #define FPGA_AJTAG_BOUNDARY_MINOR 7 // read/write boundary pins of the aux board FPGA
#define FPGA_SJTAG_CHANNELS 4 // Number of sensor ports for JTAG
#define FPGA_SJTAG_MINOR_OFFSET 8 // Minors range start for the sensor port JTAG
#define FPGA_SJTAG_BOUNDARY_OFFSET 12 // Minors range start for the sensor port boundary
#define X3X3_EXIF_EXIF 0 // read encoded Exif data (SEEK_END, #define X3X3_EXIF_EXIF 0 // read encoded Exif data (SEEK_END,
#define X3X3_EXIF_META 1 // write metadata, concurently opened files. All writes atomic #define X3X3_EXIF_META 1 // write metadata, concurently opened files. All writes atomic
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment