建立 MAG160C 逆向工程交接仓库
This commit is contained in:
@@ -0,0 +1,178 @@
|
||||
/* Capture type=0 frames and dump spatial/temporal statistics to reveal
|
||||
* fixed-pattern noise (mura), bad pixels, and startup-vs-settled behavior.
|
||||
* Writes per-pixel mean over N frames + frame-level row/col profiles.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <windows.h>
|
||||
#include <libusb.h>
|
||||
|
||||
#define W 160
|
||||
#define H 120
|
||||
#define NPIX (W * H)
|
||||
|
||||
static libusb_context *g_ctx;
|
||||
static libusb_device_handle *g_h;
|
||||
|
||||
static int sendcmd(unsigned magic, unsigned param, int len) {
|
||||
unsigned char cmd[8] = {0};
|
||||
cmd[0] = (unsigned char)(magic);
|
||||
cmd[1] = (unsigned char)(magic >> 8);
|
||||
cmd[2] = (unsigned char)(magic >> 16);
|
||||
cmd[3] = (unsigned char)(magic >> 24);
|
||||
if (len >= 8) {
|
||||
cmd[4] = (unsigned char)(param);
|
||||
cmd[5] = (unsigned char)(param >> 8);
|
||||
cmd[6] = (unsigned char)(param >> 16);
|
||||
cmd[7] = (unsigned char)(param >> 24);
|
||||
}
|
||||
int xfer = 0;
|
||||
if (libusb_bulk_transfer(g_h, 0x03, cmd, len, &xfer, 2000)) return -1;
|
||||
unsigned char resp[0x1000];
|
||||
if (libusb_bulk_transfer(g_h, 0x82, resp, sizeof(resp), &xfer, 2000)) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* return 1 on a valid type=0 frame */
|
||||
static int read_frame(unsigned char *frame, unsigned *type) {
|
||||
unsigned char hdr[64];
|
||||
static unsigned prev = 0xffffffff;
|
||||
int xfer = 0;
|
||||
if (libusb_bulk_transfer(g_h, 0x81, hdr, sizeof(hdr), &xfer, 200) && xfer < 28) return 0;
|
||||
if (xfer < 28) return 0;
|
||||
unsigned m = (unsigned)hdr[0] | ((unsigned)hdr[1] << 8) |
|
||||
((unsigned)hdr[2] << 16) | ((unsigned)hdr[3] << 24);
|
||||
if (m != 0x1bb1b11b) return 0;
|
||||
unsigned c = (unsigned)hdr[4] | ((unsigned)hdr[5] << 8) |
|
||||
((unsigned)hdr[6] << 16) | ((unsigned)hdr[7] << 24);
|
||||
if (c == prev) return 0;
|
||||
prev = c;
|
||||
if (libusb_bulk_transfer(g_h, 0x81, frame, 40000, &xfer, 200) || xfer < 38400) return 0;
|
||||
*type = (unsigned)hdr[12];
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int nframes = argc > 1 ? atoi(argv[1]) : 200;
|
||||
const char *out = argc > 2 ? argv[2] : "frame_stats.txt";
|
||||
if (libusb_init(&g_ctx)) return 1;
|
||||
libusb_device **list = NULL;
|
||||
ssize_t cnt = libusb_get_device_list(g_ctx, &list);
|
||||
for (ssize_t i = 0; i < cnt && !g_h; ++i) {
|
||||
struct libusb_device_descriptor d;
|
||||
libusb_get_device_descriptor(list[i], &d);
|
||||
if (d.idVendor == 0x833c) libusb_open(list[i], &g_h);
|
||||
}
|
||||
libusb_free_device_list(list, 1);
|
||||
if (!g_h) { printf("no device\n"); return 1; }
|
||||
libusb_set_configuration(g_h, 2);
|
||||
libusb_set_configuration(g_h, 1);
|
||||
if (libusb_claim_interface(g_h, 0)) return 1;
|
||||
sendcmd(0x6bb6b66b, 0, 4);
|
||||
sendcmd(0x6bb6b66c, 0, 4);
|
||||
sendcmd(0x6bb6b66f, 0, 4);
|
||||
sendcmd(0x6bb6b672, 0, 8);
|
||||
Sleep(100);
|
||||
sendcmd(0x6bb6b672, 0, 8);
|
||||
Sleep(300);
|
||||
sendcmd(0x6bb6b673, 0, 4);
|
||||
Sleep(700);
|
||||
|
||||
unsigned char frame[40000];
|
||||
unsigned type = 1;
|
||||
/* drain + FFC(1) after ~10 complete frames switches the stream to
|
||||
* type=0 (verified cadence) */
|
||||
int drained = 0;
|
||||
for (int i = 0; i < 120; ++i) {
|
||||
if (!read_frame(frame, &type)) { Sleep(10); continue; }
|
||||
drained++;
|
||||
if (drained == 10) {
|
||||
sendcmd(0x6bb6b672, 1, 8);
|
||||
Sleep(200);
|
||||
}
|
||||
if (type == 0) break;
|
||||
}
|
||||
if (type != 0) {
|
||||
printf("failed to reach type=0 stream\n");
|
||||
return 3;
|
||||
}
|
||||
|
||||
double mean[NPIX];
|
||||
memset(mean, 0, sizeof(mean));
|
||||
double row[H], col[W];
|
||||
memset(row, 0, sizeof(row));
|
||||
memset(col, 0, sizeof(col));
|
||||
unsigned short last[NPIX];
|
||||
double delta_sum = 0;
|
||||
int delta_n = 0;
|
||||
int got = 0, type0 = 0, type1 = 0;
|
||||
|
||||
FILE *f = fopen(out, "w");
|
||||
if (!f) return 2;
|
||||
|
||||
for (int n = 0; n < nframes; ++n) {
|
||||
if (!read_frame(frame, &type)) { Sleep(10); n--; continue; }
|
||||
got++;
|
||||
if (type) { type1++; continue; }
|
||||
type0++;
|
||||
/* frame stats */
|
||||
long fr_sum = 0;
|
||||
unsigned fr_min = 65535, fr_max = 0;
|
||||
for (int i = 0; i < NPIX; ++i) {
|
||||
unsigned v = (unsigned)frame[i * 2 + 28] | ((unsigned)frame[i * 2 + 29] << 8);
|
||||
mean[i] += v;
|
||||
fr_sum += v;
|
||||
if (v < fr_min) fr_min = v;
|
||||
if (v > fr_max) fr_max = v;
|
||||
if (got > 1) {
|
||||
int d = (int)v - (int)last[i];
|
||||
if (d < 0) d = -d;
|
||||
delta_sum += d;
|
||||
delta_n++;
|
||||
}
|
||||
last[i] = (unsigned short)v;
|
||||
}
|
||||
fprintf(f, "FRAME %d type0 mean=%.0f min=%u max=%u meandelta=%.1f\n",
|
||||
n, (double)fr_sum / NPIX, fr_min, fr_max,
|
||||
delta_n ? delta_sum / delta_n : 0);
|
||||
delta_sum = 0;
|
||||
delta_n = 0;
|
||||
}
|
||||
for (int i = 0; i < NPIX; ++i) mean[i] /= type0 ? type0 : 1;
|
||||
for (int y = 0; y < H; ++y) {
|
||||
double s = 0;
|
||||
for (int x = 0; x < W; ++x) s += mean[y * W + x];
|
||||
row[y] = s / W;
|
||||
}
|
||||
for (int x = 0; x < W; ++x) {
|
||||
double s = 0;
|
||||
for (int y = 0; y < H; ++y) s += mean[y * W + x];
|
||||
col[x] = s / H;
|
||||
}
|
||||
/* per-pixel deviation from row+col model (mura detection) */
|
||||
fprintf(f, "\nROW_PROFILE:\n");
|
||||
for (int y = 0; y < H; ++y) fprintf(f, "%d %.1f\n", y, row[y]);
|
||||
fprintf(f, "\nCOL_PROFILE:\n");
|
||||
for (int x = 0; x < W; ++x) fprintf(f, "%d %.1f\n", x, col[x]);
|
||||
fprintf(f, "\nPIXEL_DEVIATION (mean - row - col + global):\n");
|
||||
double gm = 0;
|
||||
for (int i = 0; i < NPIX; ++i) gm += mean[i];
|
||||
gm /= NPIX;
|
||||
for (int y = 0; y < H; ++y) {
|
||||
for (int x = 0; x < W; ++x) {
|
||||
double dev = mean[y * W + x] - row[y] - col[x] + gm;
|
||||
fprintf(f, "%d %d %.1f\n", x, y, dev);
|
||||
}
|
||||
}
|
||||
fclose(f);
|
||||
printf("captured %d frames (type0=%d type1=%d) -> %s\n", got, type0, type1, out);
|
||||
|
||||
Sleep(300);
|
||||
libusb_clear_halt(g_h, 0x03);
|
||||
libusb_clear_halt(g_h, 0x82);
|
||||
sendcmd(0x6bb6b674, 0, 4);
|
||||
libusb_close(g_h);
|
||||
libusb_exit(g_ctx);
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user