diff --git a/.claude/settings.local.json b/.claude/settings.local.json index e976182..29cd9e9 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -1,7 +1,8 @@ { "permissions": { "allow": [ - "Read(//c/Windows/Fonts//**)" + "Read(//c/Windows/Fonts//**)", + "Read(//z/work/**)" ], "deny": [ "Edit", diff --git a/mpp/sample/it66021/src/Main.c b/mpp/sample/it66021/src/Main.c index afdf27b..74b8800 100644 --- a/mpp/sample/it66021/src/Main.c +++ b/mpp/sample/it66021/src/Main.c @@ -19,6 +19,13 @@ #include "it6602.h" #include "it6602_reg.h" +#include +#include +#include +#include +#include + + char Firmware_date[] = __DATE__; char Firmware_time[] = __TIME__; @@ -52,6 +59,66 @@ void InitMessage() } +static void dump_regs(unsigned long addr, int n) +{ + unsigned long page = addr & ~0xfffUL; + int fd = open("/dev/mem", O_RDWR | O_SYNC); + void *m; + int i; + + if (fd < 0) { perror("open /dev/mem"); return; } + m = mmap(NULL, 0x10000, PROT_READ | PROT_WRITE, MAP_SHARED, fd, page); + if (m == MAP_FAILED) { perror("mmap"); close(fd); return; } + + for (i = 0; i < n; i++) + printf(" %08lx: %08x\n", addr + i * 4, + *(volatile unsigned int *)((char *)m + (addr - page) + i * 4)); + + munmap(m, 0x10000); + close(fd); +} + +static void it66021_reset_gpio(void) +{ + unsigned long base = 0x11095000; /* PL061 gpio_chip5 */ + int fd = open("/dev/mem", O_RDWR | O_SYNC); + void *m; + + if (fd < 0) { perror("open"); return; } + m = mmap(NULL, 0x1000, PROT_READ | PROT_WRITE, MAP_SHARED, fd, base); + if (m == MAP_FAILED) { perror("mmap"); close(fd); return; } + + printf("GPIO5 before: DATA=0x%02x DIR=0x%02x AFSEL=0x%02x DEN=0x%02x\n", + *(volatile unsigned char *)((char *)m + 0x008), + *(volatile unsigned char *)((char *)m + 0x400), + *(volatile unsigned char *)((char *)m + 0x420), + *(volatile unsigned char *)((char *)m + 0x51c)); + + /* 释放复位(bit1):输出 + 数字使能 + 拉高 */ + *(volatile unsigned char *)((char *)m + 0x400) |= 0x02; /* DIR */ + *(volatile unsigned char *)((char *)m + 0x51c) |= 0x02; /* DEN */ + *(volatile unsigned char *)((char *)m + 0x008) = 0x02; /* DATA(PL061 掩码写,bit1) */ + + usleep(10000); + printf("GPIO5 after : DATA=0x%02x DIR=0x%02x\n", + *(volatile unsigned char *)((char *)m + 0x008), + *(volatile unsigned char *)((char *)m + 0x400)); +} + + +void DumpI2cRegs(const char *tag) +{ + printf("===== I2C dump: %s =====\n", tag); + printf("-- I2C1 controller 0x11061000 --\n"); + dump_regs(0x11061000, 64); + printf("-- I2C0 controller 0x11060000 --\n"); + dump_regs(0x11060000, 64); + printf("-- CRG 0x11014280 (I2C0) --\n"); + dump_regs(0x11014280, 2); + printf("-- CRG 0x11014288 (I2C1) --\n"); + dump_regs(0x11014288, 2); + printf("=============================\n"); +} @@ -64,14 +131,19 @@ void InitMessage() void main( void ) { - USHORT loopinterval; + USHORT loopinterval = 0; InitMessage(); open_i2c_fd(); + it66021_reset_gpio(); + DumpI2cRegs("before IT6602_fsm_init"); /* ← 加这里,最重要 */ + delay1ms(1000); //for power sequence IT6602_fsm_init(); + DumpI2cRegs("after IT6602_fsm_init"); /* ← 再加这里 */ + while(1) { loopinterval += getloopTicCount(); @@ -85,3 +157,4 @@ void main( void ) } + diff --git a/mpp/sample/it66021/src/Utility.c b/mpp/sample/it66021/src/Utility.c index c20d139..8e354a1 100644 --- a/mpp/sample/it66021/src/Utility.c +++ b/mpp/sample/it66021/src/Utility.c @@ -23,7 +23,7 @@ USHORT getloopTicCount() { usleep(5000); - return 1; + return 5; } diff --git a/mpp/sample/it66021/src/hi_i2c_ops.c b/mpp/sample/it66021/src/hi_i2c_ops.c index d191b53..0bda03a 100644 --- a/mpp/sample/it66021/src/hi_i2c_ops.c +++ b/mpp/sample/it66021/src/hi_i2c_ops.c @@ -59,7 +59,8 @@ static int fd; int open_i2c_fd() { int ret; - fd = open("/dev/i2c-1", O_RDWR); + //fd = open("/dev/i2c-1", O_RDWR); + fd = open("/dev/i2c-0", O_RDWR); if (fd<0) { printf("Open i2c dev error!\n"); diff --git a/mpp/sample/it66021/src/it6602.c b/mpp/sample/it66021/src/it6602.c index f08a041..bd47e1a 100644 --- a/mpp/sample/it66021/src/it6602.c +++ b/mpp/sample/it66021/src/it6602.c @@ -450,17 +450,17 @@ struct IT6602_REG_INI IT6602_HDMI_INIT_TABLE[] = { {REG_RX_010, 0xFF, 0x17}, //[4]Auto Video Reset [2]Int Reset [1]Audio Reset [0]Video Reset - {REG_RX_011, 0xFF, 0x1F}, //Port 0¡G[4]EQ Reset [3]CLKD5 Reset [2]CDR Reset [1]HDCP Reset [0]All logic Reset - {REG_RX_018, 0xFF, 0x1F}, //Port 1¡G[4]EQ Reset [3]CLKD5 Reset [2]CDR Reset [1]HDCP Reset [0]All logic Reset + {REG_RX_011, 0xFF, 0x1F}, //Port 0[4]EQ Reset [3]CLKD5 Reset [2]CDR Reset [1]HDCP Reset [0]All logic Reset + {REG_RX_018, 0xFF, 0x1F}, //Port 1[4]EQ Reset [3]CLKD5 Reset [2]CDR Reset [1]HDCP Reset [0]All logic Reset - {REG_RX_012, 0xFF, 0xF8}, //Port 0¡G[7:3] MHL Logic reset + {REG_RX_012, 0xFF, 0xF8}, //Port 0[7:3] MHL Logic reset {REG_RX_010, 0xFF, 0x10}, //[4]Auto Video Reset [2]Int Reset [1]Audio Reset [0]Video Reset - {REG_RX_011, 0xFF, 0xA0}, //Port 0¡G[7] Enable Auto Reset when Clock is not stable [5]Enable Auto Reset - {REG_RX_018, 0xFF, 0xA0}, //Port 1¡G[7] Enable Auto Reset when Clock is not stable [5]Enable Auto Reset + {REG_RX_011, 0xFF, 0xA0}, //Port 0[7] Enable Auto Reset when Clock is not stable [5]Enable Auto Reset + {REG_RX_018, 0xFF, 0xA0}, //Port 1[7] Enable Auto Reset when Clock is not stable [5]Enable Auto Reset - {REG_RX_012, 0xFF, 0x00}, //Port 0¡G[7:3] MHL Logic reset + {REG_RX_012, 0xFF, 0x00}, //Port 0[7:3] MHL Logic reset {REG_RX_00F, 0x03, 0x01}, //change bank 1 //2013-0430 Andrew suggestion {REG_RX_1B0, 0x03, 0x01}, // MHL Port Set HPD = 0 at Power On initial state @@ -473,8 +473,8 @@ struct IT6602_REG_INI IT6602_HDMI_INIT_TABLE[] = { {REG_RX_00F, 0x03, 0x00}, //change bank 0 //2013-0430 Andrew suggestion - {REG_RX_017, 0xC0, 0x80}, //Port 0¡G[7:6] = 10 invert Port 0 input HCLK , CLKD5I //2013-0430 Andrew suggestion - {REG_RX_01E, 0xC0, 0x00}, //Port 1¡G[7:6] = 00 invert Port 1 input TMDS , CLKD5I //2013-0430 Andrew suggestion + {REG_RX_017, 0xC0, 0x80}, //Port 0[7:6] = 10 invert Port 0 input HCLK , CLKD5I //2013-0430 Andrew suggestion + {REG_RX_01E, 0xC0, 0x00}, //Port 1[7:6] = 00 invert Port 1 input TMDS , CLKD5I //2013-0430 Andrew suggestion #ifdef Enable_IT6602_CEC {REG_RX_00E, 0xFF, 0xFF}, //for enable CEC Clock @@ -483,10 +483,10 @@ struct IT6602_REG_INI IT6602_HDMI_INIT_TABLE[] = { // {0xFE, 0x80, 0x80}, //BUS10B for FPGA - {REG_RX_016, 0x08, 0x08}, //Port 0¡G[3]1: Enable CLKD5 auto power down - {REG_RX_01D, 0x08, 0x08}, //Port 1¡G[3]1: Enable CLKD5 auto power down + {REG_RX_016, 0x08, 0x08}, //Port 0[3]1: Enable CLKD5 auto power down + {REG_RX_01D, 0x08, 0x08}, //Port 1[3]1: Enable CLKD5 auto power down -// {0x20, 0x01, 0x30}, //Port 0¡GAFE control +// {0x20, 0x01, 0x30}, //Port 0AFE control {REG_RX_02B, 0xFF, 0x07}, //FixTek3D // {REG_RX_031, 0xFF, 0x2C}, //[7:4]Enable repeater function [3:0] SCL hold time count & Update Ri sel @@ -679,7 +679,7 @@ struct IT6602_REG_INI IT6602_HDMI_INIT_TABLE[] = { #if defined(_IT66023_) //FIX_ID_016 xxxxx Support Dual Pixel Mode for IT66023 Only - {REG_RX_08C, 0x09, 0x09}, // Reg8C[0] = 1 // SPOutMode¡G// for enable IO Mapping for Signal Pixel mode + {REG_RX_08C, 0x09, 0x09}, // Reg8C[0] = 1 // SPOutMode// for enable IO Mapping for Signal Pixel mode //FIX_ID_016 xxxxx #endif @@ -711,14 +711,14 @@ static struct IT6602_REG_INI IT6602_MHL_INIT_TABLE[] = { {MHL_RX_53, 0xFF, 0x80}, //[7]=1 disable FW mode {MHL_RX_32, 0xFF, 0x0C}, //CBUS arbitration Low time - {MHL_RX_81, 0xFF, MHLVersion}, //DCAP00¡GMHL_VER_MAJOR and MINOR - {MHL_RX_82, 0xFF, (PLIM<<5)+(POW<<4)+DEV_TYPE_SINK}, //DCAP02¡GDEVICE TYPE - {MHL_RX_83, 0xFF, ADOPTER_ID_H}, //DCAP03¡GADOPTER_ID + {MHL_RX_81, 0xFF, MHLVersion}, //DCAP00MHL_VER_MAJOR and MINOR + {MHL_RX_82, 0xFF, (PLIM<<5)+(POW<<4)+DEV_TYPE_SINK}, //DCAP02DEVICE TYPE + {MHL_RX_83, 0xFF, ADOPTER_ID_H}, //DCAP03ADOPTER_ID {MHL_RX_84, 0xFF, ADOPTER_ID_L}, - {MHL_RX_8B, 0xFF, DEVICE_ID_H}, //DCAP0B¡GDEVICE_ID + {MHL_RX_8B, 0xFF, DEVICE_ID_H}, //DCAP0BDEVICE_ID {MHL_RX_8C, 0xFF, DEVICE_ID_L}, - {MHL_RX_28, 0x0F, 0x00}, //Port 0¡G[0] = 0 RS value of CH1 if req_setEQ=1 //2013-0430 Andrew suggestion + {MHL_RX_28, 0x0F, 0x00}, //Port 0[0] = 0 RS value of CH1 if req_setEQ=1 //2013-0430 Andrew suggestion {MHL_RX_0F, 0x20, 0x20}, //[5]Guard band swap when Pack Mode //FIX_ID_004 xxxxx //Add 100ms calibration for Cbus @@ -2092,11 +2092,11 @@ void IT66023OutputPixelModeSet(unsigned char bSignalPixelMode) { HDMIRX_VIDEO_PRINTF(("IT66023OutputPixelModeSet( ) 111111111111 Signal Pixel Mode\r\n")); // 1 . Signal Pixel Mode - // Reg0D[3] = 0 // EnPHFClk¡G0 for disable PHFCLK for signal pixel mode - // Reg8C[0] = 1 // SPOutMode¡G// for enable IO Mapping for Signal Pixel mode - // Reg8C[3] = 1 // VDIO3en¡G// for enable QA IO - // Reg8B[0] = 0 // EnDualPixel¡G0 for disable Dual Pixel mode - // Reg8B[7] = 1 // PWDDownDualData¡G// for gating dual pix data output + // Reg0D[3] = 0 // EnPHFClk0 for disable PHFCLK for signal pixel mode + // Reg8C[0] = 1 // SPOutMode// for enable IO Mapping for Signal Pixel mode + // Reg8C[3] = 1 // VDIO3en// for enable QA IO + // Reg8B[0] = 0 // EnDualPixel0 for disable Dual Pixel mode + // Reg8B[7] = 1 // PWDDownDualData// for gating dual pix data output hdmirxset(REG_RX_00D, 0x08, 0x00); hdmirxset(REG_RX_08C, 0x09, 0x09); hdmirxset(REG_RX_08B, 0x81, 0x80); @@ -2106,11 +2106,11 @@ void IT66023OutputPixelModeSet(unsigned char bSignalPixelMode) { HDMIRX_VIDEO_PRINTF(("IT66023OutputPixelModeSet( ) 00000000000000 Dual Pixel Mode\r\n")); // 2. Dual Pixel Mode - // Reg0D[3] = 1 // EnPHFClk¡G// for enable PHFCLK for Dual pixel mode - // Reg8C[0] = 0 // SPOutMode¡G0 for Disable IO Mapping for Dual Pixel mode - // Reg8C[3] = 1 // VDIO3en¡G// for enable QA IO - // Reg8B[0] = 1 // EnDualPixel¡G// for enable Dual Pixel mode - // Reg8B[7] = 0 // PWDDownDualData¡G0 for PWD UP DUAL DATA + // Reg0D[3] = 1 // EnPHFClk// for enable PHFCLK for Dual pixel mode + // Reg8C[0] = 0 // SPOutMode0 for Disable IO Mapping for Dual Pixel mode + // Reg8C[3] = 1 // VDIO3en// for enable QA IO + // Reg8B[0] = 1 // EnDualPixel// for enable Dual Pixel mode + // Reg8B[7] = 0 // PWDDownDualData0 for PWD UP DUAL DATA hdmirxset(REG_RX_00D, 0x08, 0x08); hdmirxset(REG_RX_08C, 0x09, 0x08); hdmirxset(REG_RX_08B, 0x81, 0x01); @@ -6713,7 +6713,7 @@ static void IT6602VideoOutputEnable(unsigned char bEnableOutput) //FIX_ID_016 xxxxx Support Dual Pixel Mode for IT66023 Only #if defined(_IT66023_) - hdmirxset(REG_RX_08C, 0x08, 0x00); // Reg8C[3] = 0 // VDIO3en¡G// for disable QA IO + hdmirxset(REG_RX_08C, 0x08, 0x00); // Reg8C[3] = 0 // VDIO3en// for disable QA IO #endif //FIX_ID_016 xxxxx diff --git a/mpp/sample/it66021/src/it66021 b/mpp/sample/it66021/src/it66021 index ecc4950..e070a98 100644 Binary files a/mpp/sample/it66021/src/it66021 and b/mpp/sample/it66021/src/it66021 differ diff --git a/mpp/sample/lc6600_uart/ctrl_pnl_yt.c b/mpp/sample/lc6600_uart/ctrl_pnl_yt.c new file mode 100644 index 0000000..2351e8e --- /dev/null +++ b/mpp/sample/lc6600_uart/ctrl_pnl_yt.c @@ -0,0 +1,421 @@ +#include +#include +#include // gettimeofday +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "serial.h" +#include "uartinf.h" +#include "confile.h" +#include "udp_util.h" + +char _rx_data[1024]; + +struct lc6600_param{ + int password; + int freq; + int power; + int bw; + int ap_sta; + int ip; + int setup; +}; + +char freq1[10]; +char freq2[10]; +//char dbm1[5]; +//char dbm2[5]; + +#define RSSI_TIMEOUT_MS 3000 //超时时间 +#define RSSI_NO_SIGNAL 0x55 //无信号值 + + + +int setup_lc6600(struct lc6600_param *pparam){ + int n_read; + char *read_ok; + char str[30]; + + uart_write(ROUTE_UART, "AT+CFUN=0\r"); + n_read = uart_read(ROUTE_UART, _rx_data); + read_ok = strstr(_rx_data,"OK"); + if(read_ok == NULL){ + printf("can not exce AT+CFUN=0"); + } + sleep(1); + //password + sprintf(str,"AT^DAPI=%d\r",pparam->password); + uart_write(ROUTE_UART, str); + printf("%s\n",str); + n_read = uart_read(ROUTE_UART, _rx_data); + read_ok = strstr(_rx_data,"OK"); + if(read_ok == NULL){ + printf("can not exce AT^DAPI"); + } + sleep(1); + // 1 center 2 station + sprintf(str,"AT^DDTC=%d\r",pparam->ap_sta); + uart_write(ROUTE_UART, str); + printf("%s\n",str); + n_read = uart_read(ROUTE_UART, _rx_data); + read_ok = strstr(_rx_data,"OK"); + if(read_ok == NULL){ + printf("can not exce AT^DDTC"); + } + sleep(1); + +// sprintf(str,"AT^DDTC=%d\r",pparam->ap_sta); + uart_write(ROUTE_UART, "AT^DSTC=2\r"); + printf("AT^DSTC\n"); + n_read = uart_read(ROUTE_UART, _rx_data); + read_ok = strstr(_rx_data,"OK"); + if(read_ok == NULL){ + printf("can not exce AT^DDSTC"); + } + sleep(1); + + + // 2 5M 3 10M 4 15M 5 20M "25" dbm + sprintf(str,"AT^DRPS=,%d,\"%d\"\r",pparam->bw,pparam->power); + uart_write(ROUTE_UART, str); + printf("%s\n",str); + n_read = uart_read(ROUTE_UART, _rx_data); + read_ok = strstr(_rx_data,"OK"); + if(read_ok == NULL){ + printf("can not exce AT^DRPS\n"); + } + sleep(1); + // 01 800M 04 1.4G 08 2.4G + sprintf(str,"AT^DAOCNDI=0%d\r",pparam->freq); + uart_write(ROUTE_UART, str); + printf("%s\n",str); + n_read = uart_read(ROUTE_UART, _rx_data); + read_ok = strstr(_rx_data,"OK"); + if(read_ok == NULL){ + printf("can not exce AT^DAOCNDI\n"); + } + + sleep(1); + + + sprintf(str,"AT^NETIFCFG=2,\"192.168.2.%d\"\r",pparam->ip); + uart_write(ROUTE_UART, str); + printf("%s\n",str); + n_read = uart_read(ROUTE_UART, _rx_data); + read_ok = strstr(_rx_data,"OK"); + if(read_ok == NULL){ + printf("can not exce AT^DAOCNDI\n"); + } + + sleep(1); + + uart_write(ROUTE_UART, "AT+CFUN=1\r"); + n_read = uart_read(ROUTE_UART, _rx_data); + read_ok = strstr(_rx_data,"OK"); + if(read_ok == NULL){ + printf("can not exce AT+CFUN=1"); + } + + + +} + +static long elapsed_ms(struct timeval *start, struct timeval *end) +{ + return (end->tv_sec - start->tv_sec) * 1000L + + (end->tv_usec - start->tv_usec) / 1000L; +} + +#if 0 + +int get_rx1_freq(char *rx1){ + + char *s1; + char *s2; + char *s3; + char *s4; + int len; + int i; + + s1=strchr(rx1,','); + s2=strchr(s1+1,','); + s3=strchr(s2+1,','); + s4=strchr(s3+1,','); + + len= s2-s1-1; + + for(i=0;i0){ + buffer_freq=strstr(_rx_data,"^DRPS:"); + memcpy(freq_str,buffer_freq+6,6); + + printf("drps : %s\n",freq_str); + freq = atoi(freq_str); + + printf("freq %d \n",freq); + buffer_param[3]=freq; + }else{ + printf("no freq\n"); + } +#endif + + //freq=atoi(argv[3]); +// buffer_param[0] = 0x55; + //buffer_param[3] = 14300; + if(lc6600.ap_sta == 1){ + uart_write(ROUTE_UART, "AT^DAPR=1\r"); + // n_read = uart_read(ROUTE_UART, _rx_data); + // printf("%s\n",_rx_data); + + + while(1){ + + gettimeofday(&tv_now, NULL); + + if (tv_rx1.tv_sec == 0 || elapsed_ms(&tv_rx1, &tv_now) > RSSI_TIMEOUT_MS) { + buffer_param[1] = RSSI_NO_SIGNAL; + printf("rx1 no signal timeout\n"); + } + + if (tv_rx2.tv_sec == 0 || elapsed_ms(&tv_rx2, &tv_now) > RSSI_TIMEOUT_MS) { + buffer_param[2] = RSSI_NO_SIGNAL; + printf("rx2 no signal timeout\n"); + } + + + n_read = uart_read(ROUTE_UART, _rx_data); + + printf("%s\n",_rx_data); + +#if 1 + if(n_read > 10){ + + //ip_str=strstr(_rx_data,argv[2]); + //ip_str=strstr(_rx_data,"192.168.1.15"); + //ip_len = strlen(ip_str); + //printf("ip_str %d \n ",ip_len); + ip_str=strstr(_rx_data,argv[2]); + ip_len = strlen(argv[2]); + if(ip_str){ + //buffer_param[0] = 0x55; + //printf("ip_str %s \n ",ip_str); + memcpy(index,ip_str+(ip_len+2),1); + //printf("index %s \n ",index); + + if(strcmp(index, "1") == 0){ + memcpy(rssi1,ip_str+(ip_len+5),3); + dbm1 = atoi(rssi1); + printf("++dbm1:%d\n",dbm1); + buffer_param[1] = dbm1; + gettimeofday(&tv_rx1, NULL); + } + + if(strcmp(index, "2") == 0){ + memcpy(rssi2,ip_str+(ip_len+5),3); + dbm2 = atoi(rssi2); + printf("++dbm2:%d\n",dbm2); + buffer_param[2] = dbm2; + gettimeofday(&tv_rx2, NULL); + } + + }else{ + printf("no signal\n"); + } + + } + else{ + printf("no \n"); + uart_write(ROUTE_UART, "AT^DAPR=1\r"); + // buffer_param[0] = 0xAA; + } + +#endif + } + } + +} diff --git a/mpp/sample/uart2net_mesh/ctrl_pnl_suzhou.c b/mpp/sample/uart2net_mesh/ctrl_pnl_suzhou.c new file mode 100644 index 0000000..d690d1f --- /dev/null +++ b/mpp/sample/uart2net_mesh/ctrl_pnl_suzhou.c @@ -0,0 +1,404 @@ +#include +#include +#include // gettimeofday +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* 新增:clock_gettime / clock_nanosleep */ +#include +#include "serial.h" +#include "uartinf.h" +#include + +#define RECV_PORT 12000 // UDP接收端口 +#define SEND_PORT 12001 // 发送端口(UART转NET) + +/* ===================== 网络帧协议定义 ===================== */ +#define NET_FRAME_LEN 32 /* 收/发报文固定长度 */ +#define NET_TAIL 0xBB /* 帧尾 */ + +#define PAYLOAD_LEN 30 /* 帧长度 byte0..29 */ +#define BYTE_MODE 30 /* 接收帧 mode 字段偏移(0-4) */ +#define BYTE_TAIL 31 /* 接收帧帧尾偏移 */ + +#define CHECKSUM_END 30 /* 校验和覆盖 byte0..byte30(含) */ +#define NET_FRAME_MAX_LEN 256 /* recvfrom 缓冲大小 */ + +#define BYTE_NOSIG0 25 /* byte25 = 视频流0无信号标志(1=无信号,0=有信号) */ +#define BYTE_NOSIG1 26 /* byte26 = 视频流1无信号标志(1=无信号,0=有信号) */ +#define BYTE_RSSI1 28 /* 信号包=RSSI1;设备包=哨兵 */ +#define BYTE_RSSI2 29 /* 信号包=RSSI2;设备包=哨兵 */ +#define SIG_MARK 0x5A /* 设备包 byte28/29 哨兵值 */ +#define SIGNAL_INTERVAL_MS 100 /* 独立信号包发送间隔(ms) */ +#define FRAME_HEAD 0x11 /* 上行帧帧头(byte0),面板校验要求 */ +#define FRAME_TAIL 0x22 /* 上行帧帧尾(byte30),面板校验要求 */ +#define FRAME_HEAD_TX 0xAA /* 下行帧帧头(byte0),设备→面板 */ + + +/* ===================== 共享内存 ===================== */ +#define SHM_MSG_NAME "/video_switch" +#define SHM_MODE_IDX 0 /* switch_mode -> shm[0](即 switch_video[0]) */ + + +static int *shm_msg = NULL; +static int *buffer_param = NULL; /* 新增:/param.txt 共享内存,供信号线程读 RSSI */ + +char _rx_data[200]; + + +static int socket_descriptor; +static struct sockaddr_in address; + +bool first = false; + +int socket_descriptor_recv; +struct sockaddr_in address_recv; +pthread_attr_t attr; +pthread_t pkts_thread; + +/* 打开共享内存 /param.txt(由 lc6600_uart 进程写入 RSSI) */ +static int *param_memory_open(void) { + int fd = shm_open("/param.txt", O_RDWR, 0777); + if (fd < 0) { + fd = shm_open("/param.txt", O_RDWR | O_CREAT, 0777); + if (fd < 0) { perror("shm_open /param.txt"); return NULL; } + if (ftruncate(fd, 4096) == -1) { perror("ftruncate /param.txt"); return NULL; } + } + int *retval = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (retval == MAP_FAILED) { perror("mmap /param.txt"); return NULL; } + return retval; +} + + +static int *switch_memory_open(void) { + char buf[128]; + int fd; + sprintf(buf, SHM_MSG_NAME); + fd = shm_open(buf, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); + if(fd < 0) { perror("shm_open"); exit(1); } + if (ftruncate(fd, 4096) == -1) { perror("ftruncate"); exit(1); } + int *retval = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + return retval; +} + + +int init_net_recv(int port){ + + int i; + struct timeval tv; + + bzero(&address_recv,sizeof(struct sockaddr_in)); + address_recv.sin_family=AF_INET; + address_recv.sin_addr.s_addr=htonl(INADDR_ANY); + address_recv.sin_port=htons(port); + + socket_descriptor_recv=socket(AF_INET,SOCK_DGRAM,0);//IPV4 + + tv.tv_sec = 2; + tv.tv_usec = 0; + if (setsockopt(socket_descriptor_recv, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) { + printf("socket option SO_RCVTIMEO not support\n"); + return -1; + } + + + + if (bind(socket_descriptor_recv, (struct sockaddr *)&address_recv, sizeof(struct sockaddr_in)) < 0) + { + perror("bind"); + exit(1); + } + + return 0; +} + + + + +int udp_init(char *ip, int port){ + + + bzero(&address,sizeof(address)); + address.sin_family=AF_INET; + address.sin_addr.s_addr=inet_addr(ip); + address.sin_port=htons(port); + + + socket_descriptor=socket(AF_INET,SOCK_DGRAM,0);//IPV4 + return 0; +} + +#if 0 +void *net_recv(void *arg) +{ + int i; + struct sockaddr_in clientAddr; + int len = sizeof(clientAddr); + int ret; + struct timeval tv; + tv.tv_sec = 5; + tv.tv_usec = 0; + if (setsockopt(socket_descriptor_recv, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) { + printf("socket option SO_RCVTIMEO not support\n"); + //return -1; + } + + char buffer_cmd[200]; + while(1){ + i = recvfrom(socket_descriptor_recv, buffer_cmd, 200, 0, (struct sockaddr*)&clientAddr, &len); + if(i>0){ + uart_write_len(ROUTE_UART,buffer_cmd,i); + } + else{ + printf(" time_out to receive data\n"); + + } + + } + +} + +#endif +#if 1 +void *net_recv(void *arg) +{ + int i, k; + struct sockaddr_in clientAddr; + socklen_t len; + struct timeval tv; + + char buffer_cmd[NET_FRAME_MAX_LEN]; + char frame_out[NET_FRAME_MAX_LEN]; + int sum; + unsigned char checksum; + + tv.tv_sec = 5; + tv.tv_usec = 0; + if (setsockopt(socket_descriptor_recv, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) + printf("socket option SO_RCVTIMEO not support\n"); + + while (1) { + len = sizeof(clientAddr); /* 每次循环重置,recvfrom 会改写 len */ + i = recvfrom(socket_descriptor_recv, buffer_cmd, NET_FRAME_MAX_LEN, 0, + (struct sockaddr*)&clientAddr, &len); + if (i <= 0) { + printf(" time_out to receive data\n"); + continue; + } + + if (i != NET_FRAME_LEN) { + printf("bad frame len=%d\n", i); + continue; + } + + /* 帧尾校验 */ + if ((unsigned char)buffer_cmd[BYTE_TAIL] != NET_TAIL) { + printf("bad tail=%02x\n", (unsigned char)buffer_cmd[BYTE_TAIL]); + continue; + } + + /* 解析 mode -> 写共享内存 */ + if (shm_msg) { + static int last_mode = -1; + int mode = (unsigned char)buffer_cmd[BYTE_MODE]; + + if (mode <= 4) { + if (mode != last_mode) { + shm_msg[SHM_MODE_IDX] = mode; //写入共享内存 viode_switch + last_mode = mode; + printf("write shm: mode=%d\n", mode); + } + } + else { + printf("filed mode=%d\n", mode); + } + } + + + /* 构造下行帧:byte0=0xAA 帧头,byte1..29 原样,byte30=0xBB 帧尾 */ + frame_out[0] = FRAME_HEAD_TX; /* [0] 帧头 0xAA */ + memcpy(frame_out + 1, buffer_cmd + 1, PAYLOAD_LEN - 1); /* [1..29] 原样 */ + frame_out[PAYLOAD_LEN] = NET_TAIL; /* [30] 帧尾 0xBB */ + + /* 校验和 = byte0..byte30 求和取低8位,写入 byte31 */ + sum = 0; + for (k = 0; k <= CHECKSUM_END; k++) + sum += (unsigned char)frame_out[k]; + checksum = sum & 0xFF; + frame_out[PAYLOAD_LEN + 1] = checksum; /* [31] 校验和 */ + + +#if 0 + /* 打印发出的包 */ + printf(" send to uart %d bytes:", NET_FRAME_LEN); + for (k = 0; k < NET_FRAME_LEN; k++) + printf(" %02x", (unsigned char)frame_out[k]); + printf("\n"); +#endif + + uart_write_len(ROUTE_UART, frame_out, NET_FRAME_LEN); //发送给串口 + } + + return NULL; +} + +#endif + +/* 独立信号包线程:与串口收包完全解耦,固定 SIGNAL_INTERVAL_MS 周期发送。 + * 用绝对时间 clock_nanosleep 对齐发送时刻,避免 sendto/printf 开销累积成漂移。 */ +void *signal_send(void *arg) +{ + char sig_frame[NET_FRAME_LEN]; + struct timespec next; + int k, sum; + + clock_gettime(CLOCK_MONOTONIC, &next); + + while (1) { + memset(sig_frame, 0, NET_FRAME_LEN); + sig_frame[0] = (char)FRAME_HEAD; /* byte0 = 0x11 */ + + /* byte25/26 = 视频流0/1无信号,byte27 = 布局开关(light_pwm_lvds 的 0x68 按键) */ + sig_frame[BYTE_NOSIG0] = (shm_msg && shm_msg[2] == 0x55) ? 1 : 0; + sig_frame[BYTE_NOSIG1] = (shm_msg && shm_msg[3] == 0x55) ? 1 : 0; + sig_frame[27] = (shm_msg && shm_msg[1]) ? 1 : 0; + printf("layout byte27 = %d\n", sig_frame[27]); + + if (buffer_param) { + sig_frame[BYTE_RSSI1] = (char)buffer_param[1]; + sig_frame[BYTE_RSSI2] = (char)buffer_param[2]; + } + sig_frame[PAYLOAD_LEN] = (char)FRAME_TAIL; /* byte30 = 0x22 */ + + sum = 0; + for (k = 0; k <= CHECKSUM_END; k++) + sum += (unsigned char)sig_frame[k]; + sig_frame[CHECKSUM_END + 1] = (char)(sum & 0xFF); + + sendto(socket_descriptor, sig_frame, NET_FRAME_LEN, 0, + (struct sockaddr *)&address, sizeof(address)); + + /* 下一个发送时刻 = 本次时刻 + 周期,与实际执行耗时无关 */ + next.tv_nsec += (long)SIGNAL_INTERVAL_MS * 1000000L; + while (next.tv_nsec >= 1000000000L) { + next.tv_sec++; + next.tv_nsec -= 1000000000L; + } + clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &next, NULL); + } + + return NULL; +} + + +int pthread_init() +{ + int ret; + pthread_t sig_thread; + + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); + ret = pthread_create(&pkts_thread, &attr, net_recv, NULL); + + if(ret){ + printf("create pthread1 error\n"); + pthread_attr_destroy(&attr); + return 1; + } + + ret = pthread_create(&sig_thread, &attr, signal_send, NULL); + if(ret){ + printf("create pthread2 error\n"); + pthread_attr_destroy(&attr); + return 1; + } + + pthread_attr_destroy(&attr); + + return 0; +} + + +int main (int argc, char *argv[]) +{ + int n_read; + int i; + int count=0; + + char buffer_send[100]; + int buffer_len; + + n_read = uart_init(ROUTE_UART, "/dev/ttyAMA4", 115200, 'N'); + if(n_read <=0 ) { + printf("open /dev/ttyAMA4 failed\n"); + return -1; + } + + + + // udp_init(argv[1], atoi(argv[2])); + // init_net_recv(atoi(argv[3])); + udp_init("127.0.0.1", SEND_PORT); // 发送目标:本机回环 12001 + init_net_recv(RECV_PORT); // 接收:0.0.0.0:12000(INADDR_ANY) + + + shm_msg = switch_memory_open(); + buffer_param = param_memory_open(); + + if (pthread_init()) { + printf("pthread_init failed\n"); + return -1; + } + + + + while(1){ + n_read = uart_read(ROUTE_UART, _rx_data); + if(n_read > 0 ){ + int k, sum = 0; + + /* 收包校验:完整 32 字节帧,帧头 0x11、帧尾 0x22、byte31 校验和正确,否则丢弃 */ + if (n_read < NET_FRAME_LEN) { + printf("drop bad frame: len=%d\n", n_read); + continue; + } + if ((unsigned char)_rx_data[0] != FRAME_HEAD || + (unsigned char)_rx_data[CHECKSUM_END] != FRAME_TAIL) { + printf("drop bad frame: head=%02x tail=%02x\n", + (unsigned char)_rx_data[0], (unsigned char)_rx_data[CHECKSUM_END]); + continue; + } + for (k = 0; k <= CHECKSUM_END; k++) + sum += (unsigned char)_rx_data[k]; + if ((unsigned char)_rx_data[31] != (sum & 0xFF)) { + printf("drop bad frame: checksum=%02x expect=%02x\n", + (unsigned char)_rx_data[31], (unsigned char)(sum & 0xFF)); + continue; + } + + /* byte28/29 固定哨兵值,RSSI 改由独立信号包承载 */ + _rx_data[BYTE_RSSI1] = (char)SIG_MARK; + _rx_data[BYTE_RSSI2] = (char)SIG_MARK; + + + /* 和校验:byte0..byte30 求和取低 8 位,写入 byte31 */ + sum = 0; + for (k = 0; k <= CHECKSUM_END; k++) + sum += (unsigned char)_rx_data[k]; + _rx_data[31] = (char)(sum & 0xFF); + + sendto(socket_descriptor, _rx_data, NET_FRAME_LEN, 0, (struct sockaddr *)&address, sizeof(address)); + } + + } + +}