diff options
author | rjkm <devnull@localhost> | 2001-09-16 22:27:38 -0300 |
---|---|---|
committer | rjkm <devnull@localhost> | 2001-09-16 22:27:38 -0300 |
commit | 7577c23439dfbc1d67e490d9dfa4cbd8e3b548ed (patch) | |
tree | c487ff687bf219ca62dadef0cbba2242b15f3324 /dvb-spec/dvbapi/frontend.tex | |
parent | 9034551a3bbc76b79a152806c781b1b8e8ea3a9a (diff) | |
download | mediapointer-dvb-s2-7577c23439dfbc1d67e490d9dfa4cbd8e3b548ed.tar.gz mediapointer-dvb-s2-7577c23439dfbc1d67e490d9dfa4cbd8e3b548ed.tar.bz2 |
added new API docs
Diffstat (limited to 'dvb-spec/dvbapi/frontend.tex')
-rw-r--r-- | dvb-spec/dvbapi/frontend.tex | 612 |
1 files changed, 612 insertions, 0 deletions
diff --git a/dvb-spec/dvbapi/frontend.tex b/dvb-spec/dvbapi/frontend.tex new file mode 100644 index 000000000..74f21225d --- /dev/null +++ b/dvb-spec/dvbapi/frontend.tex @@ -0,0 +1,612 @@ +\devsec{DVB Frontend API} + +The DVB frontend device controls the tuner and DVB demodulator hardware. +It can be accessed through \texttt{/dev/ost/frontend}. +If you are using \texttt{devfs} you can use \texttt{/dev/dvb/card0/frontend}. +The frontend device will only be made visible through \texttt{devfs} +if the corresponding card actually has a frontend. Cards which support +the DVB API but, e.g., only can play back recordings, will not offer the +frontend device. + +\devsubsec{Frontend Data Types} + +\devsubsubsec{frontend status} +\label{frontendstatus} + +Several functions of the frontend device use the feStatus data +type defined by +\begin{verbatim} +typedef uint32_t feStatus; +\end{verbatim} +to indicate the current state and/or state changes of +the frontend hardware. + +\noindent +It can take on the values +\begin{verbatim} +#define FE_HAS_POWER 1 +#define FE_HAS_SIGNAL 2 +#define FE_SPECTRUM_INV 4 +#define FE_HAS_LOCK 8 +#define TUNER_HAS_LOCK 128 +\end{verbatim} +which can be ORed together and have the following meaning: + +\medskip + +\begin{tabular}{lp{11cm}} +FE\_HAS\_POWER & the frontend is powered up and is ready to be used\\ +FE\_HAS\_SIGNAL & the frontend detects a signal above the normal noise level\\ +FE\_SPECTRUM\_INV & spectrum inversion is enabled/was necessary for lock\\ +FE\_HAS\_LOCK & frontend successfully locked to a DVB signal \\ +TUNER\_HAS\_LOCK & the tuner has a frequency lock +\end{tabular} + + +\devsubsubsec{frontend parameters} +\label{frontendparameters} + +The kind of parameters passed to the frontend device for tuning +depend on the kind of hardware you are using. +All kinds of parameters are combined as a union in the +FrontendParameters structure: +\begin{verbatim} +typedef struct { + __u32 Frequency; /* (absolute) frequency in Hz for QAM/OFDM */ + /* intermediate frequency in kHz for QPSK */ + union { + QPSKParameters qpsk; + QAMParameters qam; + OFDMParameters ofdm; + } u; +} FrontendParameters; +\end{verbatim} + +For satellite QPSK frontends you have to use QPSKParameters defined by +\begin{verbatim} +typedef struct { + __u32 SymbolRate; /* symbol rate in Symbols per second */ + CodeRate FEC_inner; /* forward error correction (see above) */ +} QPSKParameters; +\end{verbatim} +for cable QAM frontend you use the QAMParameters structure +\begin{verbatim} +typedef struct { + __u32 SymbolRate; /* symbol rate in Symbols per second */ + CodeRate FEC_inner; /* forward error correction (see above) */ + CodeRate FEC_outer; /* forward error correction (see above) */ + Modulation QAM; /* modulation type (see above) */ +} QAMParameters; +\end{verbatim} +DVB-T frontends are supported by the OFDMParamters structure +\begin{verbatim} +typedef struct { + BandWidth bandWidth; + CodeRate HP_CodeRate; /* high priority stream code rate */ + CodeRate LP_CodeRate; /* low priority stream code rate */ + Modulation Constellation; /* modulation type (see above) */ + TransmitMode TransmissionMode; + GuardInterval guardInterval; + Hierarchy HierarchyInformation; +} OFDMParameters; +\end{verbatim} + +In the case of QPSK frontends the Frequency field specifies the intermediate +frequency, i.e. the offset which is effectively added to the local oscillator +frequency (LOF) of the LNB. +The intermediate frequency has to be specified in units of kHz. +For QAM and OFDM frontends the Frequency specifies the absolute frequency +and is given in Hz. + +\noindent +The possible values for the FEC\_inner field are +\begin{verbatim} +enum { + FEC_AUTO, + FEC_1_2, + FEC_2_3, + FEC_3_4, + FEC_5_6, + FEC_7_8, + FEC_NONE +}; +\end{verbatim} +which correspond to error correction rates of $1\over 2$, $2\over 3$, etc., +no error correction or auto detection. + +\noindent +For cable and terrestrial frontends (QAM and OFDM) one also has to +specify the quadrature modulation mode which can be one of the following: +\begin{verbatim} +typedef enum +{ QPSK, + QAM_16, + QAM_32, + QAM_64, + QAM_128, + QAM_256 +} QAM_TYPE; +\end{verbatim} + +Finally, there are several more parameters for OFDM: +\begin{verbatim} +typedef enum { + TRANSMISSION_MODE_2K, + TRANSMISSION_MODE_8K +} TransmitMode; +\end{verbatim} + +\begin{verbatim} +typedef enum { + BANDWIDTH_8_MHZ, + BANDWIDTH_7_MHZ, + BANDWIDTH_6_MHZ +} BandWidth; +\end{verbatim} + +\begin{verbatim} +typedef enum { + GUARD_INTERVAL_1_32, + GUARD_INTERVAL_1_16, + GUARD_INTERVAL_1_8, + GUARD_INTERVAL_1_4 +} GuardInterval; +\end{verbatim} + +\begin{verbatim} +typedef enum { + HIERARCHY_NONE, + HIERARCHY_1, + HIERARCHY_2, + HIERARCHY_4 +} Hierarchy; +\end{verbatim} + + +\devsubsubsec{frontend events} +\label{frontendevents} + +\begin{verbatim} +enum { + FE_UNEXPECTED_EV, + FE_COMPLETION_EV, + FE_FAILURE_EV +}; +\end{verbatim} + +\begin{verbatim} +typedef struct { + EventType type; /* type of event, FE_UNEXPECTED_EV, ... */ + long timestamp; /* time in seconds since 1970-01-01 */ + + union { + struct { + FrontendStatus previousStatus; /* status before event */ + FrontendStatus currentStatus; /* status during event */ + } unexpectedEvent; + FrontendParameters completionEvent; /* parameters for which the + tuning succeeded */ + FrontendStatus failureEvent; /* status at failure (e.g. no lock) */ + } u; +} FrontendEvent; +\end{verbatim} + +\begin{verbatim} +struct qpskRegister { + uint8_t chipId; + uint8_t address; + uint8_t value; +}; +\end{verbatim} + +\begin{verbatim} +struct qamRegister { + uint8_t chipId; + uint8_t address; + uint8_t value; +}; +\end{verbatim} + +\begin{verbatim} +struct qpskFrontendInfo { + uint32_t minFrequency; + uint32_t maxFrequency; + uint32_t maxSymbolRate; + uint32_t minSymbolRate; + uint32_t hwType; + uint32_t hwVersion; +}; +\end{verbatim} + +\begin{verbatim} +struct qamFrontendInfo { + uint32_t minFrequency; + uint32_t maxFrequency; + uint32_t maxSymbolRate; + uint32_t minSymbolRate; + uint32_t hwType; + uint32_t hwVersion; +}; +\end{verbatim} + +\begin{verbatim} +typedef enum { + FE_POWER_ON, + FE_POWER_STANDBY, + FE_POWER_SUSPEND, + FE_POWER_OFF +} powerState_t; +\end{verbatim} + + +\clearpage + + +\devsubsec{Frontend Function Calls} + +\function{open()}{ + int open(const char *deviceName, int flags);}{ + This system call opens a named frontend device (e.g. /dev/ost/qpskfe + for a satellite frontend or /dev/ost/qamfe for a cable frontend) + for subsequent use. + + The device can be opened in read-only mode, which only allows + monitoring of device status and statistics, or read/write mode, which allows + any kind of use (e.g. performing tuning operations.) + + In a system with multiple front-ends, it is usually the case that multiple + devices cannot be open in read/write mode simultaneously. As long as a + front-end device is opened in read/write mode, other open() calls in + read/write mode will either fail or block, depending on whether + non-blocking or blocking mode was specified. + A front-end device opened in blocking mode can later be put into non-blocking + mode (and vice versa) using the F\_SETFL command of the fcntl system call. + This is a standard system call, documented in the Linux manual page for fcntl. + When an open() call has succeeded, the device will be ready for use in the + specified mode. This implies that the corresponding hardware is powered up, + and that other front-ends may have been powered down to make that possible. + + }{ + const char *deviceName & Name of specific video device.\\ + int flags & A bit-wise OR of the following flags:\\ + & \hspace{1em} O\_RDONLY read-only access\\ + & \hspace{1em} O\_RDWR read/write access\\ + & \hspace{1em} O\_NONBLOCK open in non-blocking mode \\ + & \hspace{1em} (blocking mode is the default)\\ + }{ + ENODEV & Device driver not loaded/available.\\ + EINTERNAL & Internal error.\\ + EBUSY & Device or resource busy.\\ + EINVAL & Invalid argument.\\ +} + +\function{close()}{ + int close(int fd);}{ + This system call closes a previously opened front-end device. + After closing a front-end device, its corresponding hardware might be + powered down automatically, but only when this is needed to open + another front-end device. + To affect an unconditional power down, it should be done explicitly using + the OST\_SET\_POWER\_STATE ioctl. + This system call closes a previously opened audio device. + }{ + int fd & File descriptor returned by a previous call to open().\\ + }{ + EBADF & fd is not a valid open file descriptor.\\ +} + +\ifunction{OST\_SELFTEST}{ + int ioctl(int fd, int request = OST\_SELFTEST);}{ + This ioctl call initiates an automatic self-test of the front-end hardware. + This call requires read/write access to the device. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals OST\_SELFTEST for this command.\\ + }{ + -1& Self test failure.\\ +} + +\ifunction{OST\_SET\_POWER\_STATE}{ + int ioctl(int fd, int request = OST\_SET\_POWER\_STATE, uint32\_t state);}{ + This ioctl call, implemented in many OST device drivers, enables direct + control over the power state of the hardware device, which may be on, off, + standby, or suspend. The latter two are low-power modes, which disable all + functionality of the device until turned on again. In contrast to the off + state, however, the standby and suspend states resume operation in the same + state as when the device was active. The only difference between the standby + and suspend states is a different tradeoff between resume time and power + consumption. Power consumption may be lower in the suspend state at the + cost of a longer resume time.\\ + A device that implements this call does not necessarily support two low-power + modes. If it only supports one low-power state, or none at all, the + OST\_SET\_POWER\_STATE operation for the missing states will + still succeed, but + it will be mapped to an existing state as per this table: \\ + \begin{center} + \begin{tabular}[h]{cll} + number of low-power & requested state & resulting state\\ + states supported &&\\ + \\ + 1 & standby & suspend \\ + 1 & suspend & suspend \\ + 0 & standby & on \\ + 0 & suspend & on + \end{tabular} + \end{center}\\ + For other cases where a required state is missing, an error code will be + returned. This can happen if a device does not support the power-off state, + but nevertheless implements this ioctl operation for control of low-power + states. + When opening a device in read/write mode, the driver ensures that the + corresponding hardware device is turned on initially. If the device is + later turned off or put in suspend mode, it has to be explicitly turned on + again.\\ + This call requires read/write access to the device. (Note that the power + management driver can affect the power state of devices without using this + ioctl operation, so having exclusive read/write access to a device does not + imply total control over the power state.) + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals OST\_SET\_POWER\_STATE for this command.\\ + uint32\_t state & Requested power state. One of: \\ + & + \begin{tabular}[h]{ll} + OST\_POWER\_ON& turn power on\\ + OST\_POWER\_STANDBY& set device in standby mode\\ + OST\_POWER\_SUSPEND& set device in suspend mode\\ + OST\_POWER\_OFF& turn power off\\ + \end{tabular} + }{ + EBADF& fd is not a valid open file descriptor.\\ + EINVAL& Illegal state, or not available on this device.\\ + EPERM & Permission denied (needs read/write access).\\ + ENOSYS& Function not available for this device. +} + +\ifunction{FE\_GET\_POWER\_STATE}{ + int ioctl(int fd, int request = OST\_GET\_POWER\_STATE, uint32\_t *state);}{ + This ioctl call, implemented in many OST device drivers, obtains the power + state of the hardware device, which may be on, off, standby, or suspend. + A device that implements this call does not necessarily support all four states. + If there is only one low-power state, the suspend state will be returned for + that state. If there is no low-power state, the on state will be reported + standby and suspend states will be equivalent to the on state. + For this command, read-only access to the device is sufficient. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals OST\_GET\_POWER\_STATE for this command.\\ + uint32\_t *state & Requested power state. One of: \\ + & + \begin{tabular}[h]{ll} + OST\_POWER\_ON& power is on\\ + OST\_POWER\_STANDBY& device in standby mode\\ + OST\_POWER\_SUSPEND& device in suspend mode\\ + OST\_POWER\_OFF& power is off\\ + \end{tabular} + }{ + EBADF& fd is not a valid open file descriptor.\\ + EINVAL& Illegal state, or not available on this device.\\ + EFAULT& state points to invalid address.\\ + ENOSYS& Function not available for this device. +} + +\ifunction{FE\_READ\_STATUS}{ + int ioctl(int fd, int request = FE\_READ\_STATUS, feStatus *status);}{ + This ioctl call returns status information about the front-end. + This call only requires read-only access to the device. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals FE\_READ\_STATUS for this command.\\ + struct feStatus *status&Points to the location where the front-end + status word is to be stored. + }{ + EBADF& fd is not a valid open file descriptor.\\ + EFAULT& status points to invalid address.\\ +} + +\ifunction{FE\_READ\_BER}{ + int ioctl(int fd, int request = FE\_READ\_BER, uint32\_t *ber);}{ + This ioctl call returns the bit error rate for the signal currently + received/demodulated by the front-end. For this command, read-only access + to the device is sufficient. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals FE\_READ\_BER for this command.\\ + uint32\_t *ber & The bit error rate, as a multiple of $10^{-9}$, + is stored into *ber.\\ + & Example: a value of 2500 corresponds to a bit error + rate of $2.5\cdot 10^{-6}$, or 1 error in 400000 bits. + }{ + EBADF& fd is not a valid open file descriptor.\\ + EFAULT& ber points to invalid address.\\ + ENOSIGNAL& There is no signal, thus no meaningful bit error + rate. Also returned if the front-end is not turned on.\\ + ENOSYS& Function not available for this device. +} + +\ifunction{FE\_READ\_SNR}{ + int ioctl(int fd, int request = FE\_READ\_SNR, int32\_t *snr);}{ + This ioctl call returns the signal-to-noise ratio for the signal currently + received by the front-end. For this command, read-only access to the device + is sufficient. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals FE\_READ\_SNR for this command.\\ + int32\_t *snr& The signal-to-noise ratio, as a multiple of + $10^{-6}$ dB, is stored into *snr.\\ + & Example: a value of 12,300,000 corresponds + to a signal-to-noise ratio of 12.3 dB. +}{ + EBADF& fd is not a valid open file descriptor.\\ + EFAULT& snr points to invalid address.\\ + ENOSIGNAL& There is no signal, thus no meaningful signal + strength value. Also returned if front-end is not turned on.\\ + ENOSYS& Function not available for this device. +} + +\ifunction{FE\_READ\_SIGNAL\_STRENGTH}{ + int ioctl( int fd, int request = FE\_READ\_SIGNAL\_STRENGTH, int32\_t *strength); +}{ +This ioctl call returns the signal strength value for the signal currently +received by the front-end. For this command, read-only access to the device +is sufficient. +}{ +int fd & File descriptor returned by a previous call to open().\\ +int request & Equals FE\_READ\_SIGNAL\_STRENGTH for this command.\\ +int32\_t *strength & The signal strength value, as a multiple of + $10^{-6 }$ dBm, + is stored into *strength. \\ + &Example: a value of -12,500,000 corresponds to a signal + strength value of -12.5 dBm. +}{ + EBADF& fd is not a valid open file descriptor.\\ + EFAULT& status points to invalid address.\\ + ENOSIGNAL& There is no signal, thus no meaningful signal + strength value. Also returned if front-end is not turned on.\\ + ENOSYS& Function not available for this device. +} + +\ifunction{FE\_READ\_UNCORRECTED\_BLOCKS}{ + int ioctl( int fd, int request = FE\_READ\_UNCORRECTED\_BLOCKS, uint32\_t *ublocks); }{ + This ioctl call returns the number of uncorrected blocks detected by + the device driver during its lifetime. + For meaningful measurements, the increment in + block count during a specific time interval should be calculated. + For this command, read-only access to the device is sufficient.\\ + Note that the counter will wrap to zero after its maximum count has + been reached. +}{ +int fd & File descriptor returned by a previous call to open().\\ +int request & Equals FE\_READ\_UNCORRECTED\_BLOCKS for this command.\\ +uint32\_t *ublocks & The total number of uncorrected blocks seen +by the driver so far. +}{ + EBADF& fd is not a valid open file descriptor.\\ + EFAULT& ublocks points to invalid address.\\ + ENOSYS& Function not available for this device. +} + + +\ifunction{FE\_GET\_NEXT\_FREQUENCY}{ + int ioctl( int fd, int request = FE\_GET\_NEXT\_FREQUENCY, uint32\_t *freq);}{ + When scanning a frequency range, it is desirable to use a scanning step size + that is as large as possible, yet small enough to be able to lock to any signal + within the range. + This ioctl operation does just that - it increments a given frequency by a + step size suitable for efficient scanning. + The step size used by this function may be a quite complex function of the given + frequency, hardware capabilities, and parameter settings of the device. Thus, a + returned result is only valid for the current state of the device. + For this command, read-only access to the device is sufficient.\\ + Note that scanning may still be excruciatingly slow on some hardware, for + other reasons than a non-optimal scanning step size. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals FE\_GET\_NEXT\_FREQUENCY for this command.\\ + uint32\_t *freq& Input: a given frequency \\ + & Output: the frequency corresponding to + the next higher frequency setting.\\ + }{ + EBADF& fd is not a valid open file descriptor.\\ + EFAULT& freq points to invalid address.\\ + EINVAL& Maximum supported frequency reached.\\ + ENOSYS& Function not available for this device. +} + +\ifunction{FE\_GET\_NEXT\_SYMBOL\_RATE}{ + int ioctl( int fd, int request = FE\_GET\_NEXT\_SYMBOL\_RATE, uint32\_t *symbolRate); + }{ + When scanning a range of symbol rates (e.g. for "blind acquisition") it is + desirable to use a scanning step size that is as large as possible, yet + small enough to detect any valid signal within the range. This ioctl + operation does just that - it increments a given symbol rate by a step size + suitable for efficient scanning. + The step size used by this function may be a quite complex function of the given + symbol rate, hardware capabilities, and parameter settings of the device. + Thus, a returned result is only valid for the current state of the device. + For this command, read-only access to the device is sufficient. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals FE\_GET\_NEXT\_SYMBOL\_RATE for this command.\\ + uint32\_t *symbolRate& Input: a given symbol rate \\ + & Output: the symbol rate corresponding to + the next higher symbol rate.\\ + }{ + EBADF& fd is not a valid open file descriptor.\\ + EFAULT& symbolRate points to invalid address.\\ + EINVAL& Maximum supported symbol rate reached.\\ + ENOSYS& Function not available for this device. +} + +\ifunction{FE\_SET\_FRONTEND}{ + int ioctl(int fd, int request = FE\_SET\_FRONTEND, struct FrontendParameters *p);}{ + This ioctl call starts a tuning operation using specified parameters. + The result of this call will be successful if the parameters were valid and + the tuning could be initiated. + The result of the tuning operation in itself, however, will arrive + asynchronously as an event (see documentation for FE\_GET\_EVENT + and FrontendEvent.) + If a new FE\_SET\_FRONTEND operation is initiated before the previous + one was completed, + the previous operation will be aborted in favor of the new one. + This command requires read/write access to the device. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals FE\_SET\_FRONTEND for this command.\\ + struct FrontendParameters *p& Points to parameters for tuning operation.\\ + }{ + EBADF& fd is not a valid open file descriptor.\\ + EFAULT& p points to invalid address.\\ + EINVAL& Maximum supported symbol rate reached.\\ +} + +\ifunction{FE\_GET\_EVENT}{ + int ioctl(int fd, int request = QPSK\_GET\_EVENT, struct qpskEvent *ev);}{ + This ioctl call returns an event of type qpskEvent if available. If an event + is not available, the behavior depends on whether the device is in blocking + or non-blocking mode. In the latter case, the call fails immediately with + errno set to EWOULDBLOCK. In the former case, the call blocks until an event + becomes available.\\ + The standard Linux poll() and/or select() system calls can be used with the + device file descriptor to watch for new events. For select(), the file + descriptor should be included in the exceptfds argument, and for poll(), + POLLPRI should be specified as the wake-up condition. + Since the event queue allocated is rather small (room for 8 events), the queue + must be serviced regularly to avoid overflow. If an overflow happens, the + oldest event is discarded from the queue, and an error (EBUFFEROVERFLOW) occurs + the next time the queue is read. After reporting the error condition in this + fashion, subsequent QPSK\_GET\_EVENT calls will return events from the queue as + usual.\\ + For the sake of implementation simplicity, this command requires read/write + access to the device. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals QPSK\_GET\_EVENT for this command.\\ + struct qpskEvent *ev&Points to the location where the event, if any, is to be stored. + }{ + EBADF& fd is not a valid open file descriptor.\\ + EFAULT& ev points to invalid address.\\ + EWOULDBLOCK & There is no event pending, and the device is in + non-blocking mode.\\ + EBUFFEROVERFLOW &\\ +& Overflow in event queue - one or more events were lost.\\ +} + +\ifunction{FE\_GET\_INFO}{ + int ioctl(int fd, int request = FE\_GET\_INFO, struct FrontendInfo *info);}{ + This ioctl call returns information about the front-end. + This call only requires read-only access to the device. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals FE\_GET\_INFO for this command.\\ + struct qpskFrontendInfo *info & Points to the location where the front-end + information is to be stored. + }{ + EBADF& fd is not a valid open file descriptor.\\ + EFAULT& info points to invalid address.\\ +} + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "dvbapi" +%%% End: |