Paparazzi UAS  v5.10_stable-5-g83a0da5-dirty
Paparazzi is a free software Unmanned Aircraft System.
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
libisp.c
Go to the documentation of this file.
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <stdint.h>
4 #include <fcntl.h>
5 #include <errno.h>
6 #include <string.h>
7 #include <unistd.h>
8 #include <sys/mman.h>
9 #include <sys/ioctl.h>
10 
11 #include "libisp.h"
12 
13 #define AVI_BASE 0x400000
14 #define AVI_SIZE 0x100000
15 #define AVI_MASK (AVI_SIZE - 1)
16 
18 {
24 };
25 
26 /* IOCTL implemented in AVI drivers */
27 #define AVI_ISP_IOGET_OFFSETS _IOR('F', 0x33, struct avi_isp_offsets)
28 
29 /* Raw accesses */
30 #define readl(_addr) (*((volatile uint32_t *)(_addr)))
31 #define writel(_val, _addr) (*((volatile uint32_t *)(_addr)) = _val)
32 
33 static const unsigned isp_bases[] = {
38  AVI_ISP_GREEN_IMBALANCE + AVI_ISP_GREEN_IMBALANCE_GREEN_RED_COEFF_MEM,
39  AVI_ISP_GREEN_IMBALANCE + AVI_ISP_GREEN_IMBALANCE_GREEN_BLUE_COEFF_MEM,
45  AVI_ISP_LENS_SHADING_CORRECTION + AVI_ISP_LENS_SHADING_CORRECTION_RED_COEFF_MEM,
46  AVI_ISP_LENS_SHADING_CORRECTION + AVI_ISP_LENS_SHADING_CORRECTION_GREEN_COEFF_MEM,
47  AVI_ISP_LENS_SHADING_CORRECTION + AVI_ISP_LENS_SHADING_CORRECTION_BLUE_COEFF_MEM,
52  0, /* GAMMA conf */
56  0, /* CHROMA */
57  0, /* STATS YUV*/
66 };
67 
72 static int avi_isp_get_offsets_fd(int fd, struct avi_isp_offsets *off)
73 {
74  if (ioctl(fd, AVI_ISP_IOGET_OFFSETS, off) < 0) {
75  printf("sizeof: %d, %X\n", sizeof(struct avi_isp_offsets), AVI_ISP_IOGET_OFFSETS);
76  perror("ioctl(AVI_ISP_IOGET_OFFSETS) failed");
77  return -1;
78  }
79 
80  return 0;
81 }
82 
87 static int open_isp_fd(struct libisp_context *ctx, int fd)
88 {
89  struct avi_isp_offsets off;
90  int i;
91 
92  ctx->devmem = open("/dev/mem", O_RDWR);
93 
94  if (ctx->devmem < 0) {
95  perror("Can't open /dev/mem");
96  goto open_failed;
97  }
98 
99  ctx->avi_base = (unsigned long) mmap(NULL, AVI_SIZE,
100  PROT_READ | PROT_WRITE,
101  MAP_SHARED, ctx->devmem, AVI_BASE & ~AVI_MASK);
102 
103  if (ctx->avi_base == (unsigned long) MAP_FAILED) {
104  perror("mmap failed");
105  goto mmap_failed;
106  }
107 
108  if (avi_isp_get_offsets_fd(fd, &off) < 0)
109  goto get_offsets_failed;
110 
111  /* Compute all the sub-modules offsets */
112  /* Chain Bayer */
113  for (i = chain_bayer_inter ; i < gamma_corrector ; i++)
114  ctx->offsets[i] = ctx->avi_base + isp_bases[i] + off.chain_bayer;
115 
116  ctx->offsets[gamma_corrector] = ctx->avi_base + isp_bases[i++] + off.gamma_corrector;
117  ctx->offsets[gamma_corrector_ry_lut] = ctx->avi_base + isp_bases[i++] + off.gamma_corrector;
118  ctx->offsets[gamma_corrector_gu_lut] = ctx->avi_base + isp_bases[i++] + off.gamma_corrector;
119  ctx->offsets[gamma_corrector_bv_lut] = ctx->avi_base + isp_bases[i++] + off.gamma_corrector;
120  ctx->offsets[chroma] = ctx->avi_base + isp_bases[i++] + off.chroma;
121  ctx->offsets[statistics_yuv] = ctx->avi_base + isp_bases[i++] + off.statistics_yuv;
122  ctx->offsets[statistics_yuv_ae_histogram_y] = ctx->avi_base + isp_bases[i++] + off.statistics_yuv;
123 
124  /* Chain YUV */
125  for (i = chain_yuv_inter ; i < ISP_NODE_NR ; i++)
126  ctx->offsets[i] = ctx->avi_base + isp_bases[i] + off.chain_yuv;
127 
128  return 0;
129 
130 get_offsets_failed:
131  munmap((void *) ctx->avi_base, AVI_SIZE);
132 
133 mmap_failed:
134  close(ctx->devmem);
135 
136 open_failed:
137  return -1;
138 }
139 
140 static int close_isp(struct libisp_context *ctx)
141 {
142  int ret = 0;
143 
144  if (munmap((void *) ctx->avi_base, AVI_SIZE) == -1) {
145  perror("munmap failed");
146  ret = -1;
147  }
148 
149  close(ctx->devmem);
150 
151  return ret;
152 }
153 
155 {
156  struct libisp_context isp_ctx;
157 
158  struct avi_isp_chain_bayer_inter_regs bayer_inter = {{
159  .pedestal_bypass = 1,
160  .grim_bypass = 1,
161  .rip_bypass = 1,
162  .denoise_bypass = 0,
163  .lsc_bypass = 1,
164  .chroma_aber_bypass = 1,
165  .bayer_bypass = 0,
166  .color_matrix_bypass = 0,
167  }};
168 
169  struct avi_isp_vlformat_32to40_regs vlf_32to40 = {{
170  .format = 0x0,
171  }};
172 
173  struct avi_isp_bayer_regs bay = {
174  .cfa = { ._register = 0x03 },
175  .threshold_1 = { ._register = 0x19 },
176  .threshold_2 = { ._register = 0xc8 },
177  };
178 
179  struct avi_isp_color_correction_regs cc = {
180  .coeff_01_00 = { ._register = 0xF3811477 },
181  .coeff_10_02 = { ._register = 0xFDF0021d },
182  .coeff_12_11 = { ._register = 0xFF9E0A33 },
183  .coeff_21_20 = { ._register = 0xF4DFFE25 },
184  .coeff_22 = { ._register = 0x00001B83 },
185  .offset_ry = { ._register = 0x00000000 },
186  .clip_ry = { ._register = 0x03FF0000 },
187  .offset_gu = { ._register = 0x00000000 },
188  .clip_gu = { ._register = 0x03FF0000 },
189  .offset_bv = { ._register = 0x00000000 },
190  .clip_bv = { ._register = 0x03FF0000 },
191  };
192 
193  struct avi_isp_vlformat_40to32_regs vlf_40to32 = {{
194  .format = 0x4,
195  }};
196 
197 #define COMPLEMENT_2(i, r) (((i) >= 0) ? (r) : (~(r) + 1) & 0x3fff)
198 #define Q311(i) (COMPLEMENT_2(i, (unsigned)(((ABS(i)) * (1 << 11)) + 0.5)))
199 
200 /*
201  * Chroma converter parameters to convert input stream from a given
202  * color space to another.
203  * See http://www.fourcc.org/fccyvrgb.php
204  */
205 
206 #define AVI_CONV_MATRIX(_c00, _c01, _c02, \
207  _c10, _c11, _c12, \
208  _c20, _c21, _c22) \
209  .coeff_01_00 = {{ .coeff_00 = Q311(_c00), .coeff_01 = Q311(_c01) }}, \
210  .coeff_10_02 = {{ .coeff_02 = Q311(_c02), .coeff_10 = Q311(_c10) }}, \
211  .coeff_12_11 = {{ .coeff_11 = Q311(_c11), .coeff_12 = Q311(_c12) }}, \
212  .coeff_21_20 = {{ .coeff_20 = Q311(_c20), .coeff_21 = Q311(_c21) }}, \
213  .coeff_22 = {{ .coeff_22 = Q311(_c22) }}
214 
215 #define AVI_CONV_OFFSETS(_ryin, _ryout, \
216  _guin, _guout, \
217  _bvin, _bvout) \
218  .offset_ry = {{ .offset_in = _ryin, .offset_out = _ryout }}, \
219  .offset_gu = {{ .offset_in = _guin, .offset_out = _guout }}, \
220  .offset_bv = {{ .offset_in = _bvin, .offset_out = _bvout }}
221 
222 #define AVI_CONV_CLIPS(_rymin, _rymax, \
223  _gumin, _gumax, \
224  _bvmin, _bvmax) \
225  .clip_ry = {{ .clip_min = _rymin, .clip_max = _rymax }}, \
226  .clip_gu = {{ .clip_min = _gumin, .clip_max = _gumax }}, \
227  .clip_bv = {{ .clip_min = _bvmin, .clip_max = _bvmax }}
228 
229 
230  struct avi_isp_chroma_regs chr = {
231  AVI_CONV_MATRIX( 0.213, 0.715, 0.072,
232  -0.100, -0.336, 0.436,
233  0.615, -0.515, -0.100),
234 
235  AVI_CONV_OFFSETS(0, 16,
236  0, 128,
237  0, 128),
238 
239  AVI_CONV_CLIPS(16, 235,
240  16, 240,
241  16, 240),
242  };
243 
244  if(open_isp_fd(&isp_ctx, dev->fd) < 0)
245  return -1;
246 
247  avi_isp_chain_bayer_inter_set_registers(&isp_ctx, &bayer_inter);
248  avi_isp_vlformat_32to40_set_registers(&isp_ctx, &vlf_32to40);
249  avi_isp_bayer_set_registers(&isp_ctx, &bay);
250  avi_isp_color_correction_set_registers(&isp_ctx, &cc);
251  avi_isp_vlformat_40to32_set_registers(&isp_ctx, &vlf_40to32);
252  avi_isp_chroma_set_registers(&isp_ctx, &chr);
253 
254  close_isp(&isp_ctx);
255 
256  return 0;
257 }
258 
259 
260 static inline void memcpy_to_registers(unsigned long addr,
261  const void *reg_base,
262  size_t s)
263 {
264  const uint32_t *reg = reg_base;
265  unsigned i;
266 
267  s /= sizeof(uint32_t); /* we write one register at a time */
268 
269  for (i = 0; i < s; i++)
270  writel(reg[i], addr + i * sizeof(uint32_t));
271 }
272 
273 static inline void memcpy_from_registers(void *reg_base,
274  unsigned long addr,
275  size_t s)
276 {
277  uint32_t *reg = reg_base;
278  unsigned i;
279 
280  s /= sizeof(uint32_t); /* we read one register at a time */
281 
282  for (i = 0; i < s; i++)
283  reg[i] = readl(addr + i * sizeof(uint32_t));
284 }
285 
286 #define EXPAND_AS_FUNCTION(_node) \
287  void avi_isp_ ## _node ## _set_registers(struct libisp_context *c, \
288  struct avi_isp_ ## _node ## _regs const *regs) \
289  { \
290  memcpy_to_registers(c->offsets[_node], regs, sizeof(*regs)); \
291  } \
292  \
293  void avi_isp_ ## _node ## _get_registers(struct libisp_context *c, \
294  struct avi_isp_ ## _node ## _regs *regs) \
295  { \
296  memcpy_from_registers(regs, c->offsets[_node], sizeof(*regs)); \
297  }
298 
#define AVI_ISP_GREEN_IMBALANCE_GREEN_RED_COEFF_MEM
#define AVI_ISP_DROP
Definition: reg_avi.h:49
uint32_t chain_yuv
Definition: libisp.c:23
static int close_isp(struct libisp_context *ctx)
Definition: libisp.c:140
#define AVI_CONV_CLIPS(_rymin, _rymax,_gumin, _gumax,_bvmin, _bvmax)
static const unsigned isp_bases[]
Definition: libisp.c:33
#define AVI_ISP_EDGE_ENHANCEMENT_COLOR_REDUCTION_FILTER_EE_KERNEL_COEFF
#define AVI_ISP_STATISTICS_BAYER
Definition: reg_avi.h:38
union avi_isp_vlformat_40to32_format format
#define AVI_ISP_LENS_SHADING_CORRECTION_BLUE_COEFF_MEM
#define AVI_CONV_MATRIX(_c00, _c01, _c02,_c10, _c11, _c12,_c20, _c21, _c22)
unsigned long avi_base
Definition: libisp.h:53
#define AVI_ISP_LENS_SHADING_CORRECTION_RED_COEFF_MEM
int devmem
Definition: libisp.h:52
static void memcpy_to_registers(unsigned long addr, const void *reg_base, size_t s)
Definition: libisp.c:260
#define AVI_ISP_CHAIN_BAYER_INTER
Definition: reg_avi.h:32
#define AVI_ISP_VLFORMAT_32TO40
Definition: reg_avi.h:33
#define AVI_ISP_CHAIN_YUV_INTER
Definition: reg_avi.h:46
static int avi_isp_get_offsets_fd(int fd, struct avi_isp_offsets *off)
This is taken from libisp.
Definition: libisp.c:72
uint32_t chroma
Definition: libisp.c:21
#define AVI_BASE
Definition: libisp.c:13
#define AVI_ISP_DENOISING
Definition: reg_avi.h:37
int configure_isp(struct v4l2_device *dev)
Definition: libisp.c:154
#define AVI_ISP_EDGE_ENHANCEMENT_COLOR_REDUCTION_FILTER
Definition: reg_avi.h:47
#define AVI_ISP_DEAD_PIXEL_CORRECTION_LIST_MEM
#define AVI_ISP_EDGE_ENHANCEMENT_COLOR_REDUCTION_FILTER_EE_LUT
#define AVI_ISP_IOGET_OFFSETS
Definition: libisp.c:27
#define AVI_ISP_GREEN_IMBALANCE_GREEN_BLUE_COEFF_MEM
unsigned long uint32_t
Definition: types.h:18
union avi_isp_vlformat_32to40_format format
uint32_t chain_bayer
Definition: libisp.c:19
#define AVI_ISP_DEAD_PIXEL_CORRECTION
Definition: reg_avi.h:36
#define AVI_ISP_DEAD_PIXEL_CORRECTION_CFA
static void memcpy_from_registers(void *reg_base, unsigned long addr, size_t s)
Definition: libisp.c:273
#define writel(_val, _addr)
Definition: libisp.c:31
#define AVI_ISP_CHROMATIC_ABERRATION
Definition: reg_avi.h:40
unsigned offsets[ISP_NODE_NR]
Definition: libisp.h:54
#define AVI_ISP_GAMMA_CORRECTOR_GU_LUT
static const struct usb_device_descriptor dev
Definition: usb_ser_hw.c:73
uint32_t statistics_yuv
Definition: libisp.c:22
#define AVI_CONV_OFFSETS(_ryin, _ryout,_guin, _guout,_bvin, _bvout)
union avi_isp_color_correction_coeff_01_00 coeff_01_00
uint32_t gamma_corrector
Definition: libisp.c:20
#define AVI_ISP_GAMMA_CORRECTOR_BV_LUT
int fd
Definition: serial.c:26
#define AVI_SIZE
Definition: libisp.c:14
#define AVI_ISP_COLOR_CORRECTION
Definition: reg_avi.h:42
#define AVI_ISP_I3D_LUT
Definition: reg_avi.h:48
static int open_isp_fd(struct libisp_context *ctx, int fd)
This is taken from libisp.
Definition: libisp.c:87
#define AVI_DEFINE_NODE(EXPANDER)
Definition: libisp.h:7
#define AVI_ISP_BAYER
Definition: reg_avi.h:41
#define AVI_MASK
Definition: libisp.c:15
#define AVI_ISP_I3D_LUT_CLIP_MODE
#define AVI_ISP_LENS_SHADING_CORRECTION_GREEN_COEFF_MEM
#define AVI_ISP_LENS_SHADING_CORRECTION
Definition: reg_avi.h:39
#define AVI_ISP_PEDESTAL
Definition: reg_avi.h:34
#define AVI_ISP_VLFORMAT_40TO32
Definition: reg_avi.h:43
#define AVI_ISP_I3D_LUT_LUT_OUTSIDE
#define AVI_ISP_GREEN_IMBALANCE
Definition: reg_avi.h:35
#define EXPAND_AS_FUNCTION(_node)
Definition: libisp.c:286
#define readl(_addr)
Definition: libisp.c:30
#define AVI_ISP_STATISTICS_YUV_AE_HISTOGRAM_Y
#define AVI_ISP_I3D_LUT_LUT_INSIDE
union avi_isp_bayer_cfa cfa
Definition: avi_isp_bayer.h:50
#define AVI_ISP_GAMMA_CORRECTOR_RY_LUT
int fd
The file pointer to the device.
Definition: v4l2.h:51