//---------------------------------------------------------------- // Analog Devices ADV7123 Video DAC: XJEase device file // (with MAX1246 SPI bus DAC on CN20) // ADV7123.xje Revision: 1.15 // (c)2004-2007 XJTAG Limited // // Disclaimer: XJTAG makes no guarantees whatsoever // about this code. You use it at your own risk ... // This code requires XJTAG version 1.4 or later. // // See XJTAG Application note AN2 for a description // of this device file: www.xjtag.com // // This file tests Non-JTAG Video Device using Test()(INT result) //---------------------------------------------------------------- DEVICE NAME := "Video DAC ADV7123" PINS RED := 48, 47, 46, 45, 44, 43, 42, 41, 40, 39; GREEN := 10, 9, 8, 7, 6, 5, 4, 3, 2, 1; BLUE := 23, 22, 21, 20, 19, 18, 17, 16, 15, 14; nBLANK := 11; nSYNC := 12; CLK := 24; SDOUT := CN20.15; SDIN := CN20.12; VCC := CN20.13; SCLK := CN20.14; END; DISABLE DEVICE // Power must be applied to ADC at all times to avoid // any input being driven above the power rail. VCC := 1; END; TEST COVERAGE SDOUT := OPEN HI LO; SDIN := OPEN HI LO; SCLK := OPEN HI LO; VCC := OPEN HI LO; RED := SHORTS OPEN HI LO; GREEN := SHORTS OPEN HI LO; BLUE := SHORTS OPEN HI LO; nBLANK := OPEN HI LO; nSYNC := OPEN HI LO; END; END; //------------------------------------------------------ // Constants //------------------------------------------------------ // ADC channel assignment CONST INT RED_CHANNEL := 0; CONST INT GREEN_CHANNEL := 1; CONST INT BLUE_CHANNEL := 2; CONST INT SPARE_CHANNEL := 3; // Set for additional debug output CONST INT DEBUG := FALSE; // Return codes CONST INT PASS := FALSE; CONST INT FAIL := TRUE; //------------------------------------------------------ // ADC Parameters //------------------------------------------------------ CONST INT ADC_VREF_MV := 2048; CONST INT ADC_NUM_BITS := 12; //------------------------------------------------------ // DAC Parameters //------------------------------------------------------ CONST INT DAC_NUM_BITS := 10; CONST INT DAC_FULLSCALE_MV := 1400; // DAC Red/Blue output voltage (mV) at full scale CONST INT DAC_SYNCOFFSET_MV := 600; // DAC Green output voltage blank level offset //------------------------------------------------------ // Test //------------------------------------------------------ Test()(INT result) INT channel; PRINT("Starting Video DAC Tests...\n"); // Initialise the ADC (after HSYNC and VSYNC // tests which will power off the device). ADC_Init()(); // Test the data channels FOR channel := RED_CHANNEL TO BLUE_CHANNEL IF channel = RED_CHANNEL THEN PRINT("Testing RED channel "); END; IF channel = GREEN_CHANNEL THEN PRINT("Testing GREEN channel "); END; IF channel = BLUE_CHANNEL THEN PRINT("Testing BLUE channel "); END; Test_Channel(channel)(result); PRINT("\n"); IF result THEN PRINT("Channel ", channel, " testing failed.\n"); result := FAIL; RETURN; END; END; // Tests completed OK PRINT("Video DAC tests completed OK.\n"); result := PASS; RETURN; END; //------------------------------------------------------ // Test_Channel // Test either red, green or blue channel as required. //------------------------------------------------------ Test_Channel(INT channel WIDTH 2)(INT result) INT adc_value WIDTH 12; INT bit; INT dac_value WIDTH 10; INT last_adc_value WIDTH 12; IF DEBUG THEN PRINT("Testing channel ", channel, "...\n"); END; result := FAIL; // Check for a valid channel requested. IF ((channel > BLUE_CHANNEL) || (channel < RED_CHANNEL)) THEN PRINT("Invalid ADC channel ", channel, " requested.\n"); RETURN; END; // Check channel value during blanking and, for the green channel, // confirm that the blanking level is above the sync level. SET nSYNC := 1, nBLANK := 0, RED := 0x3ff, GREEN := 0x3ff, BLUE := 0x3ff, CLK:=0; SET CLK := 1; FLUSH; SLEEP(100); ADC_Read(channel)(adc_value); IF (channel=GREEN_CHANNEL) THEN IF (adc_value < 0x400) THEN PRINT("ERROR - Green Blanking level wrong.\n"); RETURN; END; ELSE IF (adc_value > 1) THEN PRINT("ERROR during BLANKING.\n"); RETURN; END; END; // Check channel value during sync. SET nSYNC := 0, nBLANK := 0, RED := 0x3ff, GREEN := 0x3ff, BLUE := 0x3ff, CLK:=0; SET CLK:=1; ADC_Read(channel)(adc_value); IF (adc_value > 1) THEN PRINT("ERROR during SYNC.\n"); RETURN; END; last_adc_value := adc_value; // De-activate blank and sync inputs. SET nSYNC:= 0, nBLANK:=1; // Check channel value for each DAC digital bit [9..0]. FOR bit := 0 FOR 11 IF (bit = 10) THEN dac_value := 0b1111111111; ELSE dac_value := (1<>6; END; IF DEBUG THEN PRINT("Channel ", channel, " tested OK.\n"); END; result := PASS; END; //------------------------------------------------------ // Compare_ADC_Values //------------------------------------------------------ Check_ADC_Values(INT v1, INT v2)() INT diff; IF (v1 > v2) THEN diff := v1 - v2; ELSE diff := v2 - v1; END; IF (diff > 1) THEN PRINT("ADC Value ", HEX(v1), " error, expected value = 0x", HEX(v2), "\n"); IF !DEBUG THEN EXIT; END; END; END; //------------------------------------------------------ // Calc_DAC_Output // Calculate the voltage output for a given digital value //------------------------------------------------------ Calc_DAC_Output(INT value WIDTH 10)(INT mV) mV := (DAC_FULLSCALE_MV * value); mV := mV / (1 << DAC_NUM_BITS); END; //------------------------------------------------------ // Calc_ADC_Output // return the expected ADC reading for a voltage input //------------------------------------------------------ Calc_ADC_Output(INT mV)(INT value WIDTH 12) INT v; v := mV * (1 << ADC_NUM_BITS); END; //------------------------------------------------------ // ADCInit //------------------------------------------------------ ADC_Init()() // Power the device off and on again to reset - all pins must be low when power is off. SET VCC := 0, RED := 0, GREEN := 0, BLUE := 0, nBLANK := 0, nSYNC := 0, CLK := 0, SDOUT := I, SCLK := 0, SDIN := 0; FLUSH; SLEEP(10); // Now power the device on again. SET VCC := 1; FLUSH; SLEEP(20); END; //------------------------------------------------------ // ADC_Read //------------------------------------------------------ ADC_Read(INT channel WIDTH 2)(INT result WIDTH 12) INT value WIDTH 16; INT sel WIDTH 3; INT command WIDTH 8; IF (channel = 0) THEN sel := 1; END; IF (channel = 1) THEN sel := 5; END; IF (channel = 2) THEN sel := 2; END; IF (channel = 3) THEN sel := 6; END; // Unipolar, single-ended, internal clock mode, selected channel. command := 1[0] : sel[2..0] : 0x0e[3..0]; SPI_WriteSerial(command); SPI_ReadSerial()(value); // Value is held in top 12 bits. result := value[15..4]; IF (value[3..0] != 0) THEN PRINT("\nVGA Test cable response error - is the cable connected?\n"); EXIT; END; IF DEBUG THEN PRINT("ADC value for channel ", channel, " is 0x", HEX(result), "\n"); END; END; //------------------------------------------------------------------- // SPI bus interface routines //------------------------------------------------------------------- // Write to the SPI peripheral (MSB first). SPI_WriteSerial(INT value)() INT i; FOR i := 0 FOR 8 SET SCLK := 0, SDIN := value[7 - i]; SET SCLK := 1; END; SET SCLK :=0; END; // Read bits from the SPI peripheral (MSB out first). SPI_ReadSerial()(INT value) INT bit, i; value := 0; SET SDIN := 0, SCLK := 1; FOR i := 0 FOR 16 SET SCLK := 0; SET SCLK := 1,bit := SDOUT; value := (value << 1) | bit; END; SET SCLK := 0; END;