#include #include #include #include #include //define O_WRONLY and O_RDONLY #include /* mux- */ #include /* -System V */ #include /* ioctl - BSD and Linux */ #include /* -XSI STREAMS */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "../inc/ispi.h" #include "../inc/dac38j82.h" #include "../inc/isys_config.h" #include "../inc/lcd_task.h" #include "../inc/isys_com.h" #if 0//USE_38J82 int init_38j82_flg = 0; int dac38j82_spi_fd = -1; extern S_ATSC_PARA atsc_para; static void spi_dac38j82_init(void); static s8 spi_write_dac38j82(u8 addr, u16 data); static s8 spi_read_dac38j82(u8 addr, u16 *pdata); static void dac38j82_set_freq(uint32 u32freqMHz); static void cw_cfg(int cw); static void spi_dac38j82_init(void) { unsigned char mode = SPI_MODE_3 ; // 1 0 -- 1 闲时高电平, 0第一个边沿采样 unsigned char bits = 8; unsigned int speed = 100000; uint16 u16data = 0; init_spi_dev(DAC38J82_SPI_NODE, &dac38j82_spi_fd, mode, bits, speed); /* set SPI mode at 4-wire */ spi_read_dac38j82(REGMAP_ADDR_CONFIG2, &u16data); u16data |= 0x80; spi_write_dac38j82(REGMAP_ADDR_CONFIG2, u16data); // 0x2092 spi_read_dac38j82(REGMAP_ADDR_CONFIG2, &u16data); if(u16data & 0x80) { log_printf(LOG_INFO, I_SYS_STATUS, "spi mode set 4-wire done.\n"); } } static s8 spi_write_dac38j82(u8 addr, u16 data) { int ret; if (addr > 0xff) { log_printf(LOG_ERR,I_SYS_STATUS,"spi_write_dac38j82 addr error!\r\n"); return -1; } ret = spi_w(dac38j82_spi_fd, addr, data); if(ret == 0) { return 0; } else { if(ret == -1) log_printf(LOG_ERR,I_SYS_STATUS,"dac38j82_spi_fd err, < 0 \n"); else if(ret == -2) log_printf(LOG_ERR,I_SYS_STATUS,"can't send spi message, for write dac38j82_spi_fd\n"); return -1; } } static s8 spi_read_dac38j82(u8 addr, u16 *pdata) { int ret; if (addr > 0xff) { log_printf(LOG_ERR,I_SYS_STATUS,"spi_read_dac38j82 addr error!\n"); return RET_FAIL; } ret = spi_r(dac38j82_spi_fd, addr, pdata); if(ret == 0) { return 0; } else { if(ret == -1) log_printf(LOG_ERR,I_SYS_STATUS,"dac38j82_spi_fd err, < 0 \n"); else if(ret == -2) log_printf(LOG_ERR,I_SYS_STATUS,"can't send spi message, for read dac38j82_spi_fd\n"); return -1; } } /***************************************************************************** * Function : gpio_dac38j82_reset * Description : reset imx6ull's pin DA33_RESET set low -> high now only high * Input : void * Output : None * Return : * Others : * Record * 1.Date : 20220302 * Author : Shu.Wang * Modification: Created function *****************************************************************************/ static void gpio_dac38j82_reset(void) { // reset imx6ull's pin DA33_RESET set low -> high now only high log_printf(LOG_DEBUG,I_NOUSED,"RESETB : DA33_RESET 0--->1\n"); system("echo out > /sys/class/gpio/gpio116/direction"); system("echo in > /sys/class/gpio/gpio116/direction"); } /* OneShu@20220124 config20、 config21、config22 data = int(freqMHz*2^48/1920) */ static void dac38j82_set_freq(uint32 u32freqMHz) { uint16 u16data = 0; //u32freqMHz = u32freqMHz -15; uint64 u64data =(uint64) (((uint64)u32freqMHz * (uint64)(2)<<(48-1)) / (uint64)1920); log_printf(LOG_DEBUG,I_NOUSED,"do set freq %d MHz ~ (%#llx).\n", u32freqMHz, u64data); u16data = (u64data>>0) & 0xFFFF; spi_write_dac38j82(REGMAP_ADDR_CONFIG20, u16data); u16data = (u64data>>16) & 0xFFFF; spi_write_dac38j82(REGMAP_ADDR_CONFIG21, u16data); u16data = (u64data>>32) & 0xFFFF; spi_write_dac38j82(REGMAP_ADDR_CONFIG22, u16data); log_printf(LOG_DEBUG,I_NOUSED,"spi wr freq %d MHz to 38j82 success.\n", u32freqMHz); return; } // off 0x0400 // on 0x077D static void cw_cfg_config_12_13(int cw) { // gaina 0x400 0x200 0x400 0x8400 0x400 if(cw == 0) { spi_write_dac38j82(REGMAP_ADDR_CONFIG12, 0x0400); // 0x0400 0x07FF spi_write_dac38j82(REGMAP_ADDR_CONFIG13, 0x0400); // 0x0400 0x07FF }else { spi_write_dac38j82(REGMAP_ADDR_CONFIG12, 0x077D); // 0x0400 0x07FF spi_write_dac38j82(REGMAP_ADDR_CONFIG13, 0x077D); // 0x0400 0x07FF } } // (自身数值减小的那个配置,必须先配置进38j82,使实际功率先降下来,再配置后面数值增加的那个cfg来提升功率) static void cw_cfg(int cw) { log_printf(LOG_DEBUG,I_NOUSED,"cfg 38j82 cw = %d\n", cw); if(cw == 0){ // cw 变 1 spi_write_dac38j82(REGMAP_ADDR_CONFIG13, 0x0400); // ↓ spi_write_dac38j82(REGMAP_ADDR_CONFIG12, 0x0400); // ↓ spi_write_dac38j82(REGMAP_ADDR_CONFIG2, 0x20D2); // ↓ spi_write_dac38j82(REGMAP_ADDR_CONFIG3, 0xC081); // ↑ (bit0:exenable) }else if(cw == 1) { // cw 变 0 spi_write_dac38j82(REGMAP_ADDR_CONFIG3, 0x2081); // ↓ (bit0:exenable) spi_write_dac38j82(REGMAP_ADDR_CONFIG12, 0x077D); // ↑ spi_write_dac38j82(REGMAP_ADDR_CONFIG13, 0x077D); // ↑ spi_write_dac38j82(REGMAP_ADDR_CONFIG2, 0x20F2); // ↑ } } static void *monitor_config100_thr(void*args) { uint16 u16data = 0; uint32 u32data = 0; int i = 0; while(1){ for(i=0; i<9; i++){ spi_write_dac38j82(REGMAP_ADDR_CONFIG100+i, 0x0000); usleep(2); spi_read_dac38j82(REGMAP_ADDR_CONFIG100+i, &u16data); if(u16data && i==0) { log_printf(LOG_DEBUG,I_NOUSED,"monitor alarm [config%d] 0x%x\n", REGMAP_ADDR_CONFIG100+i, u16data); } } // fpga_i2c_sim_spi_read(0x08, &u32data); // printf("read jesd204b 0x08 = 0x%x\n", u32data); // fpga_i2c_sim_spi_read(0x0c, &u32data); // printf("read jesd204b 0x0c = 0x%x\n", u32data); // fpga_i2c_sim_spi_read(0x10, &u32data); // printf("read jesd204b 0x10 = 0x%x\n", u32data); // fpga_i2c_sim_spi_read(0x1C, &u32data); // printf("read jesd204b 0x1C = 0x%x\n", u32data); // fpga_i2c_sim_spi_read(0x20, &u32data); // printf("read jesd204b 0x20 = 0x%x\n", u32data); // fpga_i2c_sim_spi_read(0x24, &u32data); // printf("read jesd204b 0x24 = 0x%x\n", u32data); // fpga_i2c_sim_spi_read(0x28, &u32data); // printf("read jesd204b 0x28 = 0x%x\n", u32data); // fpga_i2c_sim_spi_read(0x2C, &u32data); // printf("read jesd204b 0x2C = 0x%x\n", u32data); // fpga_i2c_sim_spi_read(0x38, &u32data); // printf("read jesd204b 0x38 = 0x%x\n", u32data); usleep(5000000); } } static void dac38j82_setup(DAC38J82_CFG_STEP step, uint32 u32freqMHz, int cw) { u16 u16data = 0; /* 1. Set TXENABLE Low . @ FPGA 0xB8*/ /* Has do it at jesd cfg function , done */ /* 2. supply all 0.9v */ /* 3. RESET JTAG by set TRSTB Low. @regmap-config*/ /* 4. Start DACCLK, 2871 give */ if(step == DAC38J82_CFG_STEP_ONE) { /* 5. RESETB Low to reset SIF register */ /* bit0[mem_sif_reset] : 1 bit4[NCO_ena] : 1 , bit6[ mixer_ena] : 1 , bit7[sif4_ena] : 1 bit13[zero_invalid_data] : 1 */ spi_write_dac38j82(REGMAP_ADDR_CONFIG2, (cw==0) ? 0x20D3:0x20F3); log_printf(LOG_DEBUG,I_NOUSED,"only [step 0] set config2, nco en, mixer en, sif4 en, zero invalid data, sif rst 1\n"); spi_read_dac38j82(REGMAP_ADDR_CONFIG127, &u16data); log_printf(LOG_DEBUG,I_NOUSED,"one read config127=0x%x. Vendor ID is %s 1 .\n",u16data, (0x08&u16data)?" ":"not"); } if(cw == 0) cw_cfg_config_12_13(0); /* 6. Program the DAC PLL settings (config26, config49, config50, config51). If the PLL is not used, set pll_sleep and pll_reset to 1 and pll_ena to 0. pll_sleep : 1 */ spi_write_dac38j82(REGMAP_ADDR_CONFIG26, 0x0023); // 0x0020 0x00A7 0x0020 0x0127 spi_write_dac38j82(REGMAP_ADDR_CONFIG27, 0x0000); // 0x8000 0x0000 spi_write_dac38j82(REGMAP_ADDR_CONFIG47, 0x0000); // pll_n 1/5-> 0 , pll_n 2/5-> 0, pll_ena -> 0 ,pll_reset -> 1 spi_write_dac38j82(REGMAP_ADDR_CONFIG49, 0x1018); spi_write_dac38j82(REGMAP_ADDR_CONFIG50, 0x0400); spi_write_dac38j82(REGMAP_ADDR_CONFIG51, 0x8000); spi_write_dac38j82(REGMAP_ADDR_CONFIG7, 0x0000); /* 7.Program the SERDES settings (config61, config62) including the serdes_clk_sel and serdes_refclk_div. */ // cfg 59 - serdes_refclk_div --* 0x1800--->0x0800-->0x0000 0x1800 0x0800 0x1800 spi_write_dac38j82(REGMAP_ADDR_CONFIG59, 0x1800); //0x0028 - 0x0050 0x0028 spi_write_dac38j82(REGMAP_ADDR_CONFIG60, 0x0028); spi_write_dac38j82(REGMAP_ADDR_CONFIG61, 0x0088); // 0x108 -> 0x128 -0x0108 0x128 0x8128 0x128 spi_write_dac38j82(REGMAP_ADDR_CONFIG62, 0x0128); /* 8. Program the SERDES lane settings (config63, config71, config73, config74, config96). */ spi_write_dac38j82(REGMAP_ADDR_CONFIG63, 0x0000); spi_write_dac38j82(REGMAP_ADDR_CONFIG70, 0x0044); spi_write_dac38j82(REGMAP_ADDR_CONFIG71, 0x190A); spi_write_dac38j82(REGMAP_ADDR_CONFIG72, 0x31C5); // subclass2 : 0x31C5 -0x31C1 0x31C5 spi_write_dac38j82(REGMAP_ADDR_CONFIG73, 0x0000); spi_write_dac38j82(REGMAP_ADDR_CONFIG96, 0x4567); /* 9.Program clkjesd_div, cdrvser_sysref_mode, and interp */ // cfg37 log: 0x8000->0x6000 -0x0000!!!-->0x6000-0x0000-0x8000-0x6000 0x8000 0x6000 0x8000 0x6000 spi_write_dac38j82(REGMAP_ADDR_CONFIG37, 0x6000); spi_write_dac38j82(REGMAP_ADDR_CONFIG36, 0x0000); // 0x818--0x418--0x818 0x218 0x0018-0x818 spi_write_dac38j82(REGMAP_ADDR_CONFIG0, 0x281A);// 0x0818 0x2818 281A /* 10. Program the JESD settings (config3, config74-77, config79, config80-85, config92, config97). */ if(step == DAC38J82_CFG_STEP_ONE){ spi_write_dac38j82(REGMAP_ADDR_CONFIG3, (cw==0)?0xC080:0x2080 ); //0xF080 -- > 0xF081 0xC081 0xD081 0xC081 0xE081 0xc081 0xc080 log_printf(LOG_DEBUG,I_NOUSED,"step 0 set config3 0xC080, sif_txenable 0\n"); }else{ spi_write_dac38j82(REGMAP_ADDR_CONFIG3, (cw==0)?0xC081:0x2081); // 0xC081 0xF081 0xC081 log_printf(LOG_DEBUG,I_NOUSED,"step 1 set config3 0xC081, sif_txenable 1\n"); } // dual 1 spi_write_dac38j82(REGMAP_ADDR_CONFIG74, 0x013E); spi_write_dac38j82(REGMAP_ADDR_CONFIG75, 0x0003); spi_write_dac38j82(REGMAP_ADDR_CONFIG76, 0x1F00); spi_write_dac38j82(REGMAP_ADDR_CONFIG77, 0x0100); // 0x0F0F - 0x0F2F spi_write_dac38j82(REGMAP_ADDR_CONFIG78, 0x0F2F); //0x1cc1 0x1c41 -0x1c01 0x1c41 0x1cc1 spi_write_dac38j82(REGMAP_ADDR_CONFIG79, 0x1CC1); spi_write_dac38j82(REGMAP_ADDR_CONFIG80, 0x0000); spi_write_dac38j82(REGMAP_ADDR_CONFIG81, 0x00ff); spi_write_dac38j82(REGMAP_ADDR_CONFIG82, 0x00ff); spi_write_dac38j82(REGMAP_ADDR_CONFIG83, 0x0000); spi_write_dac38j82(REGMAP_ADDR_CONFIG84, 0x00ff); spi_write_dac38j82(REGMAP_ADDR_CONFIG85, 0x00ff); spi_write_dac38j82(REGMAP_ADDR_CONFIG92, 0x1100); spi_write_dac38j82(REGMAP_ADDR_CONFIG94, 0x0000); spi_write_dac38j82(REGMAP_ADDR_CONFIG95, 0x0123); spi_write_dac38j82(REGMAP_ADDR_CONFIG97, 0x0013); /* 11. Program the DIG block settings (NCO, PA protection , QMC, fractional delay, etc.) and set the preferred SYNC modes for the digital blocks (config30-32). */ spi_write_dac38j82(REGMAP_ADDR_CONFIG2, (cw==0) ? 0x20D2 : 0x20F2); // NCO_ena mixer enable 0x20D2-0x20F2 0x2092 0x20D2 log_printf(LOG_DEBUG,I_NOUSED,"set config2, nco en, mixer en, sif4 en, zero invalid data; \n"); if(step == DAC38J82_CFG_STEP_TWO && cw == 1) cw_cfg_config_12_13(1); spi_write_dac38j82(REGMAP_ADDR_CONFIG16, 0x0000); spi_write_dac38j82(REGMAP_ADDR_CONFIG18, 0x0000); spi_write_dac38j82(REGMAP_ADDR_CONFIG19, 0x0000); dac38j82_set_freq(u32freqMHz); spi_write_dac38j82(REGMAP_ADDR_CONFIG30, 0x1111); spi_write_dac38j82(REGMAP_ADDR_CONFIG31, 0x1142); // sif sync --> 1 spi_write_dac38j82(REGMAP_ADDR_CONFIG31, 0x1140); // sif sync --> 0 spi_write_dac38j82(REGMAP_ADDR_CONFIG32, 0x0000); spi_write_dac38j82(REGMAP_ADDR_CONFIG34, 0x1B00); // 0x1B1B 0x0b0b 0x1B1B spi_write_dac38j82(REGMAP_ADDR_CONFIG38, 0x3001); // mem_dither_zero[15:15] 0x3001 0x3000 0x0000 0x3001 spi_write_dac38j82(REGMAP_ADDR_CONFIG1, 0x0000); // 0x0080 /* 12 . Verify the SERDES PLL lock status by checking the SERDES PLL alarms: alarm_rw0_pll (alarm for lanes 0 through 3), alarm_rw1_pll (alarm for lanes 4 through 7).*/ spi_read_dac38j82(REGMAP_ADDR_CONFIG108, &u16data); #if 0 if(u16data & 0x02) log_printf(LOG_DEBUG,I_NOUSED,"alarm_rw1_pll alarm!\n"); if(u16data & 0x04) log_printf(LOG_DEBUG,I_NOUSED,"alarm_rw0_pll alarm!\n"); #endif /* 13. Set init_state to "0000" and jesd_reset_n to "1" to start the JESD204B link initialization.*/ spi_write_dac38j82(REGMAP_ADDR_CONFIG74, 0x0101); // state clear /* 14 .Start the SYSREF generation. */ /* 15. Enable transmission of data by asserting the TXENABLE pin or setting sif_txenable to “1”. */ if(step == DAC38J82_CFG_STEP_ONE) spi_write_dac38j82(REGMAP_ADDR_CONFIG3, (cw==0) ? 0xC081 : 0x2081); /* 16. Clear the alarms, then wait approximately 1-2µs and check values. */ /* for( i = 0; i < 9; i++){ spi_write_dac38j82(REGMAP_ADDR_CONFIG100+i, 0x0000); usleep(2); } */ /* 17. Verify that DAC output is the desired output */ jesd_reset_by_fpga(); } /***************************************************************************** * Function : cfg_dac38j82 * Description : init setup 1. Set TXENABLE low. 2. Supply all 0.9-V supplies (VDDDIG09, VDDT09, VDDDAC09, VDDCLK09), all 1.8-V supplies (VDDR18, VDDS18, VQPS18, VDDIO18, VDDAPLL18, VDDAREF18), and all 3.3-V supplies (VDDADAC33). The supplies can be powered up simultaneously or in any order. There are no specific requirements on the ramp rate for the supplies. 3. RESET the JTAG port by either toggling TRSTB low if using the JTAG port or holding TRSTB low if not using JTAG. 4. Start the DACCLK generation. 5. Toggle RESETB low to reset the SIF registers. 6. Program the DAC PLL settings (config26, config49, config50, config51). If the PLL is not used, set pll_sleep and pll_reset to “1” and pll_ena to “0”. 7. Program the SERDES settings (config61, config62) including the serdes_clk_sel and serdes_refclk_div. 8. Program the SERDES lane settings (config63, config71, config73, config74, config96). 9. Program clkjesd_div, cdrvser_sysref_mode, and interp. 10. Program the JESD settings (config3, config74-77, config79, config80-85, config92, config97). 11. Program the DIG block settings (NCO, PA protection, QMC, fractional delay, etc.) and set the preferred SYNC modes for the digital blocks (config30-32). 12. Verify the SERDES PLL lock status by checking the SERDES PLL alarms: alarm_rw0_pll (alarm for lanes 0 through 3) and alarm_rw1_pll (alarm for lanes 4 through 7). 13. Set init_state to “0000” and jesd_reset_n to “1” to start the JESD204B link initialization. 14. Start the SYSREF generation. 15. Enable transmission of data by asserting the TXENABLE pin or setting sif_txenable to “1”. 16. Clear the alarms, then wait approximately 1-2µs and check values. 17. Verify that DAC output is the desired output * Input : void * Output : None * Return : * Others : * Record * 1.Date : 20220117 * Author : Shu.Wang * Modification: Created function SPI *****************************************************************************/ int cfg_dac38j82(uint8 txfreq, int cw) { log_printf(LOG_DEBUG,I_NOUSED,"\n\n============38j82 start==================\n"); u16 u16data = 0; int i = 0; uint32 u32FreqMHz = 0; u32FreqMHz = txfreq_to_hz(txfreq); log_printf(LOG_DEBUG,I_NOUSED,"u32FreqMHz=%dMHz\n", u32FreqMHz); if(init_38j82_flg == 0){ spi_dac38j82_init(); init_38j82_flg = 1; } cfg_jesd204b(); dac38j82_setup(DAC38J82_CFG_STEP_ONE, u32FreqMHz, cw); /* Do cfg DAC38j82 option once again. */ log_printf(LOG_DEBUG,I_NOUSED,"\n\n [%s,%d] do jesd and 38j82 cfg again.\n\n",__FUNCTION__,__LINE__); cfg_jesd204b(); spi_write_dac38j82(REGMAP_ADDR_CONFIG3, (cw==0)? 0xC081 : 0x2081); // bit0:mem_sif_txenable 1 spi_read_dac38j82(REGMAP_ADDR_CONFIG127, &u16data); log_printf(LOG_DEBUG,I_NOUSED,"222[%s,%d] read config127 = 0x%x. Vendor ID is %s 1 .\n",__FUNCTION__,__LINE__,u16data, (0x08&u16data)?" ":"not"); dac38j82_setup(DAC38J82_CFG_STEP_TWO, u32FreqMHz, cw); for( i = 0; i < 9; i++) { spi_write_dac38j82(REGMAP_ADDR_CONFIG100+i, 0x0000); usleep(2); spi_read_dac38j82(REGMAP_ADDR_CONFIG100+i, &u16data); if(u16data && i==0) { printf("alarm [config%d] 0x%x\n", REGMAP_ADDR_CONFIG100+i, u16data); } } log_printf(LOG_DEBUG,I_NOUSED,"\n============38j82 end==================\n\n"); return 0; } void chang_freq(int freq_changed) { if(freq_changed > 1 || freq_changed <= 0) return; if(freq_changed){ turn_off_rf_agc_state(E_CHG_TX_FREQ); cfg_dac38j82(atsc_para.rf_para.txfreq, atsc_para.ad3_para.cw); } return; } void chang_cw(int cw_changed) { if(cw_changed > 1 || cw_changed <= 0) return ; if(cw_changed) { turn_off_rf_agc_state(E_CHG_CW); if(atsc_para.ad3_para.cw == 0) cw_cfg(0); cfg_dac38j82(atsc_para.rf_para.txfreq, atsc_para.ad3_para.cw); if(atsc_para.ad3_para.cw == 1) cw_cfg(1); } } #endif //USE_38J82