📄 play_capture_saa7119.c
字号:
/* * * Copyright (c) 2001-2007 Sigma Designs, Inc. * All Rights Reserved. Proprietary and Confidential. * *//** @file play_capture_SAA7119.c @brief device specific functions for play_capture_main application @author Christian Wolff Sean.Sekwon.Choi*/// to enable or disable the debug messages of this source file, put 1 or 0 below#if 1#define LOCALDBG ENABLE#else#define LOCALDBG DISABLE#endif#include "sample_os.h"#define ALLOW_OS_CODE 1#include "../rua/include/rua.h"#include "../rua/include/rua_property.h"#include "../dcc/include/dcc.h"#include "../rmcore/include/rmstatustostring.h"#include "../rmlibcw/include/rmlibcw.h"#include "play_capture_SAA7119.h"#include "play_capture_i2c.h"enum state_SAA7119{ INIT = 0, RUN,};struct capsam_SAA7119_instance { struct RUA *pRUA; RMuint32 I2CModuleID; struct EMhwlibI2CDeviceParameter I2CDevice; RMuint8 BaseDevice; // internal state RMuint32 state; // interrupt state // SA7119 does not have one and only interrupt status register. // each interrupt mask is matched to specific status register. RMuint32 state_sd_0x1e; RMuint32 state_sd_0x1f; RMuint32 state_0x8f; RMuint32 state_hd_0x1f; // board specific information RMuint32 XtalClock; RMuint32 SampleRate; RMuint32 MclkFactor; RMuint32 vfreq_n; RMuint32 vfreq_m; RMuint32 pixel_clk; RMuint32 h_total_size;};/********************************************************************************** internal functions (static functions)*********************************************************************************//* calculates nominal increment with 32 bit integer arithmetic *//* returns (f_in / f_out * 2 ^ frac_bits */static RMuint32 nominal_increment(RMuint32 f_in, RMuint32 f_out, RMuint32 frac_bits) { RMuint32 div; RMint32 shift; /* sanity check */ if (!f_out) { RMDBGLOG((ENABLE, "Error: clean divider output frequency not set!\n")); return 0; } /* align denominator to enumerator */ div = 0; shift = 0; while ((f_out < f_in) && ((f_out & 0x80000000) == 0)) { f_out <<= 1; shift++; } /* calculate integer part of division */ while (1) { if (f_in >= f_out) { f_in -= f_out; div |= 1; } if (! shift) break; f_out >>= 1; div <<= 1; shift--; } div <<= 1; /* calculate first frac_bits bits of fractional part */ while (1) { if (f_in & 0x80000000) { if ( ((f_in == (f_out >> 1)) && (!(f_out & 1))) || (f_in > (f_out >> 1))) { f_in -= (f_out >> 1); div |= 1; } f_in <<= 1; if (f_out & 1) f_in -= 1; } else { f_in <<= 1; if (f_in >= f_out) { f_in -= f_out; div |= 1; } } if (shift <= (((RMint32)frac_bits - 1) * -1)) break; if (div & 0x80000000) RMDBGLOG((ENABLE, "Overflow!\n")); div <<= 1; shift--; } return div;}static RMstatus Handle_RDCAP(struct capsam_SAA7119_instance *pSAA7119, struct capsam_update *pUpdate, RMuint32 reg){ /* find out TV Standard */ if (!(reg & (1 << 0))) { /* * not ready to capture * 1F:D0:RDCAP - ready for capture (all internal loops locked - 1:active 0:not active) */ printf("not ready to capture %lx \n", reg); pUpdate->VideoOff = TRUE; }else{ printf("ready to capture %lx \n", reg); pUpdate->VideoOff = FALSE; pSAA7119->state = RUN; RMDBGLOG((LOCALDBG, "state = RUN \n")); } return RM_OK;}static RMstatus Handle_COPROP(struct capsam_SAA7119_instance *pSAA7119, struct capsam_update *pUpdate, RMuint32 reg){ /* * copy protected source dtected according to macrovison */ return RM_OK;}static RMstatus Handle_COLSTR(struct capsam_SAA7119_instance *pSAA7119, struct capsam_update *pUpdate, RMuint32 reg){ /* * macrovision encoded color stripe burst detected */ return RM_OK;}static RMstatus Handle_TYPE3(struct capsam_SAA7119_instance *pSAA7119, struct capsam_update *pUpdate, RMuint32 reg){ /* * macrovision encoded color stripe burst type3 */ return RM_OK;}static RMstatus Detect_CSTD_50Hz(struct capsam_SAA7119_instance *pSAA7119, struct capsam_update *pUpdate){ RMuint32 reg_0x0e = 0; RMuint32 CSTD = 0; capsam_i2c_read_dev(pSAA7119, pSAA7119->BaseDevice, 0x0e, ®_0x0e); printf("%x\n", (int)reg_0x0e); CSTD = RMunshiftBits(reg_0x0e, 3, 4); // CSTD[2:0] switch(CSTD){ case 0x0: // PAL B D G H I (4.43MHz) pUpdate->InputTVStandardValid = TRUE; pUpdate->InputTVStandardUpdate = TRUE; pUpdate->InputTVStandard = EMhwlibTVStandard_PAL_BG; break; case 0x02: // Combination-PAL N (3.58MHz) pUpdate->InputTVStandardValid = TRUE; pUpdate->InputTVStandardUpdate = TRUE; pUpdate->InputTVStandard = EMhwlibTVStandard_PAL_N; break; case 0x05: // SECAM case 0x03: // NTSC N (3.58MHz) case 0x01: // NTSC 4.43 default: // when others, default it ot PAL_BG with 50Hz pUpdate->InputTVStandardValid = TRUE; pUpdate->InputTVStandardUpdate = TRUE; pUpdate->InputTVStandard = EMhwlibTVStandard_PAL_BG; break; } return RM_OK;}static RMstatus Detect_CSTD_60Hz(struct capsam_SAA7119_instance *pSAA7119, struct capsam_update *pUpdate){ RMuint32 reg_0x0e = 0; RMuint32 CSTD = 0; capsam_i2c_read_dev(pSAA7119, pSAA7119->BaseDevice, 0x0e, ®_0x0e); CSTD = RMunshiftBits(reg_0x0e, 3, 4); // CSTD[2:0] switch(CSTD){ case 0x0: // NTSC M (3.58MHz) pUpdate->InputTVStandardValid = TRUE; pUpdate->InputTVStandardUpdate = TRUE; pUpdate->InputTVStandard = EMhwlibTVStandard_NTSC_M; RMDBGLOG((LOCALDBG, "EMhwlibTVStandard_NTSC_M\n")); break; case 0x03: pUpdate->InputTVStandardValid = TRUE; pUpdate->InputTVStandardUpdate = TRUE; pUpdate->InputTVStandard = EMhwlibTVStandard_PAL_M; RMDBGLOG((LOCALDBG, "EMhwlibTVStandard_PAL_M\n")); break; case 0x04: pUpdate->InputTVStandardValid = TRUE; pUpdate->InputTVStandardUpdate = TRUE; pUpdate->InputTVStandard = EMhwlibTVStandard_NTSC_M_Japan; RMDBGLOG((LOCALDBG, "EMhwlibTVStandard_NTSC_M_Japan\n")); break; case 0x01: case 0x02: default: // when others, default it to NTSC with 60Hz pUpdate->InputTVStandardValid = TRUE; pUpdate->InputTVStandardUpdate = TRUE; pUpdate->InputTVStandard = EMhwlibTVStandard_NTSC_M; RMDBGLOG((LOCALDBG, "default to EMhwlibTVStandard_NTSC_M\n")); break; } return RM_OK;}static RMstatus Handle_INTL_FIDT(struct capsam_SAA7119_instance *pSAA7119, struct capsam_update *pUpdate, RMuint32 reg1f){ /* * this will find out TVstandard from the combination of interlaced(or not) and 50Hz or 60Hz * * FIDT * 0: 50Hz * 1: 60Hz * * INTL * 0: non interlaced * 1: interlaced */ RMuint8 wss_data[7]; RMuint32 wss; // FIDT: 1:60HZ 0:50HZ if (reg1f & (1 << 5)) { printf("60Hz \n"); /* * Capture Chip Analog Input Format Detection */ Detect_CSTD_60Hz(pSAA7119, pUpdate); /* * Capture Chip Digital Output Setting */ pUpdate->TVStandard = (reg1f & (1 << 7)) ? EMhwlibTVStandard_ITU_Bt656_525 : EMhwlibTVStandard_ITU_Bt656_240p; pUpdate->TVStandardValid = TRUE; pUpdate->TVStandardUpdate = TRUE; /* * WSS processing */ capsam_i2c_read_data(pSAA7119, pSAA7119->BaseDevice, 0x6B, wss_data, 7); printf("read WSS\n"); // SC: need to talk with christian. I am checking only odd field here. if (((wss_data[0] & 0xC0) == 0) && ((wss_data[3] & 0x80) == 0)) { wss = ((wss_data[3] & 0x0F) << 16) | (wss_data[2] << 8) | wss_data[1]; switch (wss & 0x03) { case 0: // NTSC WSS "4:3 frame" fprintf(stderr, "SAA7119 WSS.525: 4:3 Frame, Full Picture\n"); pUpdate->OutputAFD.ActiveFormat = EMhwlibAF_same_as_picture; pUpdate->OutputAFD.ActiveFormatValid = TRUE; pUpdate->OutputAFD.FrameAspectRatio.X = 4; pUpdate->OutputAFD.FrameAspectRatio.Y = 3; break; case 1: // NTSC WSS "16:9 frame" fprintf(stderr, "SAA7119 WSS.525: 16:9 Frame, Full Picture\n"); pUpdate->OutputAFD.ActiveFormat = EMhwlibAF_same_as_picture; pUpdate->OutputAFD.ActiveFormatValid = TRUE; pUpdate->OutputAFD.FrameAspectRatio.X = 16; pUpdate->OutputAFD.FrameAspectRatio.Y = 9; break; case 2: // NTSC WSS "16:9 in 4:3 frame" fprintf(stderr, "SAA7119 WSS.525: 4:3 Frame, Letterbox 16:9 Picture\n"); pUpdate->OutputAFD.ActiveFormat = EMhwlibAF_16x9_centered; pUpdate->OutputAFD.ActiveFormatValid = TRUE; pUpdate->OutputAFD.FrameAspectRatio.X = 4; pUpdate->OutputAFD.FrameAspectRatio.Y = 3; break; default: pUpdate->OutputAFD.ActiveFormatValid = FALSE; break; } } }else{ printf("50Hz \n"); /* * Capture Chip Analog Input Format Detection */ Detect_CSTD_50Hz(pSAA7119, pUpdate); /* * Capture Chip Digital Output Setting */ // 1F:D7:INTL - 1:interlace 0:progressive pUpdate->TVStandard = (reg1f & (1 << 7)) ? EMhwlibTVStandard_ITU_Bt656_625 : EMhwlibTVStandard_ITU_Bt656_288p; pUpdate->TVStandardValid = TRUE; pUpdate->TVStandardUpdate = TRUE; /* * WSS processing */ capsam_i2c_read_data(pSAA7119, pSAA7119->BaseDevice, 0x6B, wss_data, 7); // SC: need to talk with christian. I am checking only odd field here. if (((wss_data[0] & 0xC0) == 0) && ((wss_data[3] & 0x80) == 0)) { wss = ((wss_data[3] & 0x0F) << 16) | (wss_data[2] << 8) | wss_data[1]; pUpdate->OutputAFD.ActiveFormat = EMhwlibAF_same_as_picture; pUpdate->OutputAFD.ActiveFormatValid = TRUE; pUpdate->OutputAFD.FrameAspectRatio.X = 4; pUpdate->OutputAFD.FrameAspectRatio.Y = 3; switch (wss & 0x0F) { case 0x8 | 0x0: // PAL WSS "4:3 frame" fprintf(stderr, "SAA7119 WSS.625: 4:3 Frame, Full Picture\n"); pUpdate->OutputAFD.ActiveFormat = EMhwlibAF_same_as_picture; break; case 0x0 | 0x1: // PAL WSS "14:9 letterbox in 4:3 frame" fprintf(stderr, "SAA7119 WSS.625: 4:3 Frame, 14:9 Picture, at center\n"); pUpdate->OutputAFD.ActiveFormat = EMhwlibAF_14x9_centered; break; case 0x0 | 0x2: // PAL WSS "14:9 letterbox at top of 4:3 frame" fprintf(stderr, "SAA7119 WSS.625: 4:3 Frame, 14:9 Picture, at top\n"); pUpdate->OutputAFD.ActiveFormat = EMhwlibAF_14x9_top; break; case 0x8 | 0x3: // PAL WSS "16:9 letterbox in 4:3 frame" fprintf(stderr, "SAA7119 WSS.625: 4:3 Frame, 16:9 Picture, at center\n"); pUpdate->OutputAFD.ActiveFormat = EMhwlibAF_16x9_centered; break; case 0x0 | 0x4: // PAL WSS "16:9 letterbox at top of 4:3 frame" fprintf(stderr, "SAA7119 WSS.625: 4:3 Frame, 16:9 Picture, at top\n"); pUpdate->OutputAFD.ActiveFormat = EMhwlibAF_16x9_top; break; case 0x8 | 0x5: // PAL WSS "> 16:9 letterbox in 4:3 frame" fprintf(stderr, "SAA7119 WSS.625: 4:3 Frame, 64:27 Picture, at center\n"); pUpdate->OutputAFD.ActiveFormat = EMhwlibAF_64x27_centered; break; case 0x8 | 0x6: // PAL WSS "4:3/14:9 letterbox in 4:3 frame" fprintf(stderr, "SAA7119 WSS.625: 4:3 Frame, 4:3 Picture with relevant content in 14:9 portion, at center\n"); pUpdate->OutputAFD.ActiveFormat = EMhwlibAF_4x3_centered_prot_14x9; break; case 0x0 | 0x7: // PAL WSS "16:9 frame" fprintf(stderr, "SAA7119 WSS.625: 16:9 Frame, Full Picture\n"); pUpdate->OutputAFD.ActiveFormat = EMhwlibAF_same_as_picture; pUpdate->OutputAFD.FrameAspectRatio.X = 16; pUpdate->OutputAFD.FrameAspectRatio.Y = 9; break; default: fprintf(stderr, "SAA7119 WSS.625: Parity Error!\n"); pUpdate->OutputAFD.ActiveFormatValid = FALSE; break; } } } return RM_OK;}static RMstatus Handle_HLVLN(struct capsam_SAA7119_instance *pSAA7119, struct capsam_update *pUpdate, RMuint32 reg){ /* * horizontal and vertical loop locked * 1: unlocked * 0: both loop locked */ if((reg & (1<<6))){ pUpdate->VideoOff = TRUE; } return RM_OK;}static RMstatus Handle_DCSTD(struct capsam_SAA7119_instance *pSAA7119, struct capsam_update *pUpdate, RMuint32 reg){ /* * Color standard detection */ return RM_OK;}static RMstatus Handle_HLCK(struct capsam_SAA7119_instance *pSAA7119, struct capsam_update *pUpdate, RMuint32 reg){ return RM_OK;}static RMstatus Handle_HFLD(struct capsam_SAA7119_instance *pSAA7119, struct capsam_update *pUpdate, RMuint32 reg){ return RM_OK;}static RMstatus Handle_ERROF(struct capsam_SAA7119_instance *pSAA7119, struct capsam_update *pUpdate, RMuint32 reg){ return RM_OK;}static RMstatus Handle_VBI_IRQ(struct capsam_SAA7119_instance *pSAA7119, struct capsam_update *pUpdate, RMuint32 reg){ return RM_OK;}static RMstatus Handle_PRD_ON(struct capsam_SAA7119_instance *pSAA7119,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -