summaryrefslogtreecommitdiffstats
path: root/api/xc4000_control.c
diff options
context:
space:
mode:
Diffstat (limited to 'api/xc4000_control.c')
-rw-r--r--api/xc4000_control.c347
1 files changed, 347 insertions, 0 deletions
diff --git a/api/xc4000_control.c b/api/xc4000_control.c
new file mode 100644
index 0000000..d061c89
--- /dev/null
+++ b/api/xc4000_control.c
@@ -0,0 +1,347 @@
+//
+// control of the XC4000 via the i2c interface.
+//
+// Filename : xc4000_control.cpp
+// Generated : 1/22/2007 4:41:24 PM
+//
+// (c) 2007, Xceive Corporation
+//
+//
+// Disclaimer:
+//
+// Xceive assumes no responsibility for any consequences arising from the use
+// of this computer code, nor from any infringement of patents or the rights of
+// third parties that may result from its use. No license is granted by
+// implication or otherwise under any patent or other rights of Xceive. The
+// customer is responsible for assuring that proper design and operating
+// safeguards are observed to minimize inherent and procedural hazards. Xceive
+// assumes no responsibility for applications assistance or customer product
+// design.
+// The present computer code is not authorized for use in medical, life-support
+// equipment, or any other application involving a potential risk of severe
+// property or environmental damage, personal injury, or death without prior
+// express written approval of Xceive. Any such use is understood to be
+// entirely at the user's risk.
+//
+
+
+//#include <math.h> //for Linux
+#include "xc4000_control.h"
+#include "i2c_driver.h"
+
+#define XREG_INIT 0x00
+#define XREG_VIDEO_MODE 0x01
+#define XREG_AUDIO_MODE 0x02
+#define XREG_RF_FREQ 0x03
+#define XREG_DCODE 0x04
+#define XREG_DIRECTSITTING_MODE 0x05
+#define XREG_SEEK_MODE 0x06
+#define XREG_POWER_DOWN 0x08
+#define XREG_RF_MODE 0x0A
+#define XREG_AMPLITUDE 0x10
+
+#define XREG_ADC_ENV 0x00
+#define XREG_QUALITY 0x01
+#define XREG_FRAME_LINES 0x02
+#define XREG_HSYNC_FREQ 0x03
+#define XREG_LOCK 0x04
+#define XREG_FREQ_ERROR 0x05
+#define XREG_SNR 0x06
+#define XREG_VERSION 0x07
+#define XREG_PRODUCT_ID 0x08
+
+/* *************************************************************** */
+/* *************************************************************** */
+/* */
+/* CODE PROVIDED BY XCEIVE */
+/* */
+/* *************************************************************** */
+/* *************************************************************** */
+int xc_write_reg(unsigned short int regAddr, unsigned short int i2cData)
+{
+ unsigned char buf[4];
+ buf[0] = (regAddr >> 8) & 0xFF;
+ buf[1] = regAddr & 0xFF;
+ buf[2] = (i2cData >> 8) & 0xFF;
+ buf[3] = i2cData & 0xFF;
+ return xc_send_i2c_data(buf, 4);
+}
+
+int xc_read_reg(unsigned short int regAddr, unsigned short int *i2cData)
+{
+ unsigned char buf[2];
+ int result;
+
+ buf[0] = (regAddr >> 8) & 0xFF;
+ buf[1] = regAddr & 0xFF;
+ result = xc_send_i2c_data(buf, 2);
+ if (result!=XC_RESULT_SUCCESS)
+ return result;
+
+ result = xc_read_i2c_data(buf, 2);
+ if (result!=XC_RESULT_SUCCESS)
+ return result;
+
+ *i2cData = buf[0] * 256 + buf[1];
+ return XC_RESULT_SUCCESS;
+}
+
+int xc_load_i2c_sequence(unsigned char i2c_sequence[])
+{
+ int i,nbytes_to_send,result;
+ unsigned int length, pos, index;
+ unsigned char buf[XC_MAX_I2C_WRITE_LENGTH];
+
+ index=0;
+ while ((i2c_sequence[index]!=0xFF) || (i2c_sequence[index+1]!=0xFF))
+ {
+ length = i2c_sequence[index]* 256 + i2c_sequence[index+1];
+ if (length==0x0000)
+ {
+ //this is in fact a RESET command
+ result = xc_reset();
+ index += 2;
+ if (result!=XC_RESULT_SUCCESS)
+ return result;
+ }
+ else if (length & 0x8000)
+ {
+ //this is in fact a WAIT command
+ xc_wait(length & 0x7FFF);
+ index += 2;
+ }
+ else
+ {
+ //send i2c data whilst ensuring individual transactions do
+ //not exceed XC_MAX_I2C_WRITE_LENGTH bytes
+ index += 2;
+ buf[0] = i2c_sequence[index];
+ buf[1] = i2c_sequence[index + 1];
+ pos = 2;
+ while (pos < length)
+ {
+ if ((length - pos) > XC_MAX_I2C_WRITE_LENGTH - 2)
+ {
+ nbytes_to_send = XC_MAX_I2C_WRITE_LENGTH;
+ }
+ else
+ {
+ nbytes_to_send = (length - pos + 2);
+ }
+ for (i=2; i<nbytes_to_send; i++)
+ {
+ buf[i] = i2c_sequence[index + pos + i - 2];
+ }
+ result = xc_send_i2c_data(buf, nbytes_to_send);
+
+ if (result!=XC_RESULT_SUCCESS)
+ return result;
+
+ pos += nbytes_to_send - 2;
+ }
+ index += length;
+ }
+ }
+ return XC_RESULT_SUCCESS;
+}
+
+int xc_initialize()
+{
+ return xc_write_reg(XREG_INIT, 0);
+}
+
+int xc_SetTVStandard(unsigned short int VideoMode, unsigned short int AudioMode)
+{
+ int returnStatus = xc_write_reg(XREG_VIDEO_MODE, VideoMode);
+ if (returnStatus == XC_RESULT_SUCCESS)
+ returnStatus = xc_write_reg(XREG_AUDIO_MODE, AudioMode);
+ return returnStatus;
+}
+
+int xc_shutdown()
+{
+ return xc_write_reg(XREG_POWER_DOWN, 0);
+}
+
+int xc_enter_directsitting_mode()
+{
+ return xc_write_reg(XREG_DIRECTSITTING_MODE, 0);
+}
+
+int xc_exit_directsitting_mode()
+{
+ unsigned char buf[]={0x00,0x00,0x00,0x00,0x88};
+ return xc_send_i2c_data(buf, 5);
+}
+
+int xc_set_RF_frequency(long frequency_in_hz)
+{
+ unsigned int frequency_code;
+ if ((frequency_in_hz>1023000000) || (frequency_in_hz<1000000))
+ return XC_RESULT_OUT_OF_RANGE;
+
+ frequency_code = (unsigned int)(frequency_in_hz / 15625L);
+ return xc_write_reg(XREG_RF_FREQ ,frequency_code);
+}
+
+int xc_set_dcode( int dcode)
+{
+ return xc_write_reg(XREG_DCODE ,dcode&0x0f);
+}
+
+int xc_rf_mode(int mode)
+{
+ return xc_write_reg(XREG_RF_MODE, mode&0x01); // 0 is Air; 1 is cable
+}
+
+
+
+//int xc_set_IF_frequency(long frequency_in_hz)
+//{
+// unsigned int frequency_code = (frequency_in_hz * 1024)/1000000;
+// return xc_write_reg(XREG_IF_OUT ,frequency_code);
+//}
+
+
+int xc_get_ADC_Envelope(unsigned short int *adc_envelope)
+{
+ return xc_read_reg(XREG_ADC_ENV, adc_envelope);
+}
+
+// Obtain current frequency error
+// Refer to datasheet for values.
+int xc_get_frequency_error(long *frequency_error_hz)
+{
+ unsigned short int data;
+ short int signed_data;
+ int result;
+
+ result = xc_read_reg(XREG_FREQ_ERROR, &data);
+ if (result)
+ return result;
+
+ signed_data = (short int)data;
+ (*frequency_error_hz) = signed_data * 15625;
+
+ return 0;
+}
+
+// Obtain current lock status.
+// Refer to datasheet for values.
+int xc_get_lock_status(unsigned short int *lock_status)
+{
+ return xc_read_reg(XREG_LOCK, lock_status);
+}
+
+// Obtain Version codes.
+// Refer to datasheet for values.
+int xc_get_version(unsigned char* hw_majorversion,
+ unsigned char* hw_minorversion,
+ unsigned char* fw_majorversion,
+ unsigned char* fw_minorversion)
+{
+ unsigned short int data;
+ int result;
+
+ result = xc_read_reg(XREG_VERSION, &data);
+ if (result)
+ return result;
+
+ (*hw_majorversion) = (data>>12) & 0x0F;
+ (*hw_minorversion) = (data>>8) & 0x0F;
+ (*fw_majorversion) = (data>>4) & 0x0F;
+ (*fw_minorversion) = (data) & 0x0F;
+
+ return 0;
+}
+
+// Obtain Product ID.
+// Refer to datasheet for values.
+int xc_get_product_id(unsigned short int *product_id)
+{
+ return xc_read_reg(XREG_PRODUCT_ID, product_id);
+}
+
+// Obtain current horizontal video frequency.
+// Refer to datasheet for values.
+int xc_get_hsync_freq(int *hsync_freq_hz)
+{
+ unsigned short int regData;
+ int result;
+
+ result = xc_read_reg(XREG_HSYNC_FREQ, &regData);
+ if (result)
+ return result;
+ (*hsync_freq_hz) = ((regData & 0x0fff) * 763)/100;
+ return result;
+}
+
+ // Obtain current number of lines per frame.
+ // Refer to datasheet for values.
+int xc_get_frame_lines(unsigned short int *frame_lines)
+{
+ return xc_read_reg(XREG_FRAME_LINES, frame_lines);
+}
+
+// Obtain current video signal quality.
+// Refer to datasheet for values.
+int xc_get_quality(unsigned short int *quality)
+{
+ return xc_read_reg(XREG_QUALITY, quality);
+}
+
+unsigned short int WaitForLock()
+{
+ unsigned short int lockState = 0;
+ int watchDogCount = 40;
+ while ((lockState == 0) && (watchDogCount > 0))
+ {
+ xc_get_lock_status(&lockState);
+ if (lockState != 1)
+ {
+ xc_wait(5); // wait 5 ms
+ watchDogCount--;
+ }
+ }
+ return lockState;
+}
+
+int xc_tune_channel(long chnl_freq)//for Linux
+{
+ long freq_error, min_freq_error, max_freq_error;
+ unsigned short int quality, max_quality;
+ int res;
+ int chnl_found = 0;//for Linux
+
+ if (xc_set_RF_frequency(chnl_freq) != XC_RESULT_SUCCESS)
+ return 0;//for Linux
+ if (WaitForLock()== 1)
+ {
+ xc_wait(6);
+ res=xc_get_frequency_error(&freq_error);
+ if (res!=XC_RESULT_SUCCESS) return res;
+ max_freq_error = freq_error;
+ min_freq_error = freq_error;
+
+ xc_wait(6);
+
+ res=xc_get_frequency_error(&freq_error);
+ if (res!=XC_RESULT_SUCCESS) return res;
+ max_freq_error = (max_freq_error>freq_error) ? max_freq_error : freq_error;
+ min_freq_error = (min_freq_error<freq_error) ? min_freq_error : freq_error;
+
+ xc_wait(6);
+
+ res=xc_get_frequency_error(&freq_error);
+ if (res!=XC_RESULT_SUCCESS) return res;
+ max_freq_error = (max_freq_error>freq_error) ? max_freq_error : freq_error;
+ min_freq_error = (min_freq_error<freq_error) ? min_freq_error : freq_error;
+
+ //We got lock, but now we check that carrier is stable and that quality is sufficient
+ if ((max_freq_error-min_freq_error)<60000)
+ chnl_found = 1;//for Linux
+ //add new channel
+
+ }
+ return chnl_found;
+}