/* Copyright (c), 2004-2005,2007-2010 Trident Microsystems, Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Trident Microsystems nor Hauppauge Computer Works nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
DRXJ specific implementation of DRX driver authors: Dragan Savic, Milos Nikolic, Mihajlo Katona, Tao Ding, Paul Janssen
The Linux DVB Driver for Micronas DRX39xx family (drx3933j) was written by Devin Heitmueller <devin.heitmueller@kernellabs.com>
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*----------------------------------------------------------------------------- INCLUDE FILES
----------------------------------------------------------------------------*/
/* * \def DRXJ_DEF_I2C_ADDR * \brief Default I2C address of a demodulator instance.
*/ #define DRXJ_DEF_I2C_ADDR (0x52)
/* * \def DRXJ_DEF_DEMOD_DEV_ID * \brief Default device identifier of a demodultor instance.
*/ #define DRXJ_DEF_DEMOD_DEV_ID (1)
/* * \def DRXJ_SCAN_TIMEOUT * \brief Timeout value for waiting on demod lock during channel scan (millisec).
*/ #define DRXJ_SCAN_TIMEOUT 1000
/* * \def HI_I2C_DELAY * \brief HI timing delay for I2C timing (in nano seconds) * * Used to compute HI_CFG_DIV
*/ #define HI_I2C_DELAY 42
/* * \def HI_I2C_BRIDGE_DELAY * \brief HI timing delay for I2C timing (in nano seconds) * * Used to compute HI_CFG_BDL
*/ #define HI_I2C_BRIDGE_DELAY 750
/* * \brief Time Window for MER and SER Measurement in Units of Segment duration.
*/ #define VSB_TOP_MEASUREMENT_PERIOD 64 #define SYMBOLS_PER_SEGMENT 832
/* * \brief bit rate and segment rate constants used for SER and BER.
*/ /* values taken from the QAM microcode */ #define DRXJ_QAM_SL_SIG_POWER_QAM_UNKNOWN 0 #define DRXJ_QAM_SL_SIG_POWER_QPSK 32768 #define DRXJ_QAM_SL_SIG_POWER_QAM8 24576 #define DRXJ_QAM_SL_SIG_POWER_QAM16 40960 #define DRXJ_QAM_SL_SIG_POWER_QAM32 20480 #define DRXJ_QAM_SL_SIG_POWER_QAM64 43008 #define DRXJ_QAM_SL_SIG_POWER_QAM128 20992 #define DRXJ_QAM_SL_SIG_POWER_QAM256 43520 /* * \brief Min supported symbolrates.
*/ #ifndef DRXJ_QAM_SYMBOLRATE_MIN #define DRXJ_QAM_SYMBOLRATE_MIN (520000) #endif
/* * \def DRXJ_QAM_MAX_WAITTIME * \brief Maximal wait time for QAM auto constellation in ms
*/ #ifndef DRXJ_QAM_MAX_WAITTIME #define DRXJ_QAM_MAX_WAITTIME 900 #endif
/* * \brief Temporary register definitions. * (register definitions that are not yet available in register master)
*/
/*****************************************************************************/ /* Audio block 0x103 is write only. To avoid shadowing in driver accessing */ /* RAM addresses directly. This must be READ ONLY to avoid problems. */ /* Writing to the interface addresses are more than only writing the RAM */ /* locations */ /*****************************************************************************/ /* * \brief RAM location of MODUS registers
*/ #define AUD_DEM_RAM_MODUS_HI__A 0x10204A3 #define AUD_DEM_RAM_MODUS_HI__M 0xF000
/* * This macro is used to create byte arrays for block writes. * Block writes speed up I2C traffic between host and demod. * The macro takes care of the required byte order in a 16 bits word. * x -> lowbyte(x), highbyte(x)
*/ #define DRXJ_16TO8(x) ((u8) (((u16)x) & 0xFF)), \
((u8)((((u16)x)>>8)&0xFF)) /* * This macro is used to convert byte array to 16 bit register value for block read. * Block read speed up I2C traffic between host and demod. * The macro takes care of the required byte order in a 16 bits word.
*/ #define DRXJ_8TO16(x) ((u16) (x[0] | (x[1] << 8)))
/*============================================================================*/ /*=== HI COMMAND RELATED DEFINES =============================================*/ /*============================================================================*/
/* * \brief General maximum number of retries for ucode command interfaces
*/ #define DRXJ_MAX_RETRIES (100)
/*============================================================================*/ /*=== STANDARD RELATED MACROS ================================================*/ /*============================================================================*/
/* * \var drxj_default_comm_attr_g * \brief Default common attributes of a drxj demodulator instance.
*/ staticstruct drx_common_attr drxj_default_comm_attr_g = {
NULL, /* ucode file */ true, /* ucode verify switch */
{0}, /* version record */
44000, /* IF in kHz in case no tuner instance is used */
(151875 - 0), /* system clock frequency in kHz */
0, /* oscillator frequency kHz */
0, /* oscillator deviation in ppm, signed */ false, /* If true mirror frequency spectrum */
{ /* MPEG output configuration */ true, /* If true, enable MPEG output */ false, /* If true, insert RS byte */ false, /* If true, parallel out otherwise serial */ false, /* If true, invert DATA signals */ false, /* If true, invert ERR signal */ false, /* If true, invert STR signals */ false, /* If true, invert VAL signals */ false, /* If true, invert CLK signals */ true, /* If true, static MPEG clockrate will be used, otherwise clockrate will
adapt to the bitrate of the TS */
19392658UL, /* Maximum bitrate in b/s in case
static clockrate is selected */
DRX_MPEG_STR_WIDTH_1 /* MPEG Start width in clock cycles */
}, /* Initilisations below can be omitted, they require no user input and are initially 0, NULL or false. The compiler will initialize them to these
values when omitted. */ false, /* is_opened */
/* SCAN */
NULL, /* no scan params yet */
0, /* current scan index */
0, /* next scan frequency */ false, /* scan ready flag */
0, /* max channels to scan */
0, /* nr of channels scanned */
NULL, /* default scan function */
NULL, /* default context pointer */
0, /* millisec to wait for demod lock */
DRXJ_DEMOD_LOCK, /* desired lock */ false,
/* Power management */
DRX_POWER_UP,
/* Tuner */
1, /* nr of I2C port to which tuner is */
0L, /* minimum RF input frequency, in kHz */
0L, /* maximum RF input frequency, in kHz */ false, /* Rf Agc Polarity */ false, /* If Agc Polarity */ false, /* tuner slow mode */
{ /* current channel (all 0) */
0UL /* channel.frequency */
},
DRX_STANDARD_UNKNOWN, /* current standard */
DRX_STANDARD_UNKNOWN, /* previous standard */
DRX_STANDARD_UNKNOWN, /* di_cache_standard */ false, /* use_bootloader */
0UL, /* capabilities */
0 /* mfx */
};
/*============================================================================*/ /*=== MICROCODE RELATED STRUCTURES ===========================================*/ /*============================================================================*/
/* * struct drxu_code_block_hdr - Structure of the microcode block headers * * @addr: Destination address of the data in this block * @size: Size of the block data following this header counted in * 16 bits words * @CRC: CRC value of the data block, only valid if CRC flag is * set.
*/ struct drxu_code_block_hdr {
u32 addr;
u16 size;
u16 flags;
u16 CRC;
};
/* * \fn u32 frac28(u32 N, u32 D) * \brief Compute: (1<<28)*N/D * \param N 32 bits * \param D 32 bits * \return (1<<28)*N/D * This function is used to avoid floating-point calculations as they may * not be present on the target platform.
* frac28 performs an unsigned 28/28 bits division to 32-bit fixed point * fraction used for setting the Frequency Shifter registers. * N and D can hold numbers up to width: 28-bits. * The 4 bits integer part and the 28 bits fractional part are calculated.
R0 = (N % D) << 4; /* 32-28 == 4 shifts possible at max */
Q1 = N / D; /* integer part, only the 4 least significant bits
will be visible in the result */
/* division using radix 16, 7 nibbles in the result */ for (i = 0; i < 7; i++) {
Q1 = (Q1 << 4) | R0 / D;
R0 = (R0 % D) << 4;
} /* rounding */ if ((R0 >> 3) >= D)
Q1++;
u8 i = 0;
u32 y = 0;
u32 d = 0;
u32 k = 0;
u32 r = 0;
if (x == 0) return 0;
/* Scale x (normalize) */ /* computing y in log(x/y) = log(x) - log(y) */ if ((x & (((u32) (-1)) << (scale + 1))) == 0) { for (k = scale; k > 0; k--) { if (x & (((u32) 1) << scale)) break;
x <<= 1;
}
} else { for (k = scale; k < 31; k++) { if ((x & (((u32) (-1)) << (scale + 1))) == 0) break;
x >>= 1;
}
} /* Now x has binary point between bit[scale] and bit[scale-1]
and 1.0 <= x < 2.0 */
/* correction for division: log(x) = log(x/y)+log(y) */
y = k * ((((u32) 1) << scale) * 200);
/* remove integer part */
x &= ((((u32) 1) << scale) - 1); /* get index */
i = (u8) (x >> (scale - index_width)); /* compute delta (x-a) */
d = x & ((((u32) 1) << (scale - index_width)) - 1); /* compute log, multiplication ( d* (.. )) must be within range ! */
y += log2lut[i] +
((d * (log2lut[i + 1] - log2lut[i])) >> (scale - index_width)); /* Conver to log10() */
y /= 108853; /* (log2(10) << scale) */
r = (y >> 1); /* rounding */ if (y & ((u32)1))
r++;
return r;
}
/* * \fn u32 frac_times1e6( u16 N, u32 D) * \brief Compute: (N/D) * 1000000. * \param N nominator 16-bits. * \param D denominator 32-bits. * \return u32 * \retval ((N/D) * 1000000), 32 bits * * No check on D=0!
*/ static u32 frac_times1e6(u32 N, u32 D)
{
u32 remainder = 0;
u32 frac = 0;
/* frac = (N * 1000000) / D To let it fit in a 32 bits computation: frac = (N * (1000000 >> 4)) / (D >> 4) This would result in a problem in case D < 16 (div by 0). So we do it more elaborate as shown below.
*/
frac = (((u32) N) * (1000000 >> 4)) / D;
frac <<= 4;
remainder = (((u32) N) * (1000000 >> 4)) % D;
remainder <<= 4;
frac += remainder / D;
remainder = remainder % D; if ((remainder * 2) > D)
frac++;
/* This layer takes care of some device specific register access protocols: -conversion to short address format -access to audio block This layer is placed between the drx_dap_fasi and the rest of the drxj specific implementation. This layer can use address map knowledge whereas dap_fasi may not use memory map knowledge.
* For audio currently only 16 bits read and write register access is supported. More is not needed. RMW and 32 or 8 bit access on audio registers will have undefined behaviour. Flags (RMW, CRC reset, broadcast single/multi master) will be ignored.
TODO: check ignoring single/multimaster is ok for AUD access ?
*/
/* * \fn bool is_handled_by_aud_tr_if( u32 addr ) * \brief Check if this address is handled by the audio token ring interface. * \param addr * \return bool * \retval true Yes, handled by audio token ring interface * \retval false No, not handled by audio token ring interface *
*/ static bool is_handled_by_aud_tr_if(u32 addr)
{ bool retval = false;
/***************************** * * int drxdap_fasi_read_block ( * struct i2c_device_addr *dev_addr, -- address of I2C device * u32 addr, -- address of chip register/memory * u16 datasize, -- number of bytes to read * u8 *data, -- data to receive * u32 flags) -- special device flags * * Read block data from chip address. Because the chip is word oriented, * the number of bytes to read must be even. * * Make sure that the buffer to receive the data is large enough. * * Although this function expects an even number of bytes, it is still byte * oriented, and the data read back is NOT translated to the endianness of * the target platform. * * Output: * - 0 if reading was successful * in that case: data read is in *data. * - -EIO if anything went wrong *
******************************/
#if DRXDAP_SINGLE_MASTER /* * In single master mode, split the read and write actions. * No special action is needed for write chunks here.
*/
rc = drxbsp_i2c_write_read(dev_addr, bufx, buf,
NULL, 0, NULL); if (rc == 0)
rc = drxbsp_i2c_write_read(NULL, 0, NULL, dev_addr, todo, data); #else /* In multi master mode, do everything in one RW action */
rc = drxbsp_i2c_write_read(dev_addr, bufx, buf, dev_addr, todo,
data); #endif
data += todo;
addr += (todo >> 1);
datasize -= todo;
} while (datasize && rc == 0);
return rc;
}
/***************************** * * int drxdap_fasi_read_reg16 ( * struct i2c_device_addr *dev_addr, -- address of I2C device * u32 addr, -- address of chip register/memory * u16 *data, -- data to receive * u32 flags) -- special device flags * * Read one 16-bit register or memory location. The data received back is * converted back to the target platform's endianness. * * Output: * - 0 if reading was successful * in that case: read data is at *data * - -EIO if anything went wrong *
******************************/
/***************************** * * int drxdap_fasi_read_reg32 ( * struct i2c_device_addr *dev_addr, -- address of I2C device * u32 addr, -- address of chip register/memory * u32 *data, -- data to receive * u32 flags) -- special device flags * * Read one 32-bit register or memory location. The data received back is * converted back to the target platform's endianness. * * Output: * - 0 if reading was successful * in that case: read data is at *data * - -EIO if anything went wrong *
******************************/
/***************************** * * int drxdap_fasi_write_block ( * struct i2c_device_addr *dev_addr, -- address of I2C device * u32 addr, -- address of chip register/memory * u16 datasize, -- number of bytes to read * u8 *data, -- data to receive * u32 flags) -- special device flags * * Write block data to chip address. Because the chip is word oriented, * the number of bytes to write must be even. * * Although this function expects an even number of bytes, it is still byte * oriented, and the data being written is NOT translated from the endianness of * the target platform. * * Output: * - 0 if writing was successful * - -EIO if anything went wrong *
******************************/
/* In single master mode block_size can be 0. In such a case this I2C sequense will be visible: (1) write address {i2c addr, 4 bytes chip address} (2) write data {i2c addr, 4 bytes data } (3) write address (4) write data etc... Address must be rewritten because HI is reset after data transport and expects an address.
*/
todo = min(block_size, datasize); if (todo == 0) {
u16 overhead_size_i2c_addr = 0;
u16 data_block_size = 0;
if ((st != 0) && (first_err == 0)) { /* at the end, return the first error encountered */
first_err = st;
}
bufx = 0;
todo = min(data_block_size, datasize);
}
memcpy(&buf[bufx], data, todo); /* write (address if can do and) data */
st = drxbsp_i2c_write_read(dev_addr,
(u16) (bufx + todo),
buf,
(struct i2c_device_addr *)(NULL),
0, (u8 *)(NULL));
if ((st != 0) && (first_err == 0)) { /* at the end, return the first error encountered */
first_err = st;
}
datasize -= todo;
data += todo;
addr += (todo >> 1);
} while (datasize);
return first_err;
}
/***************************** * * int drxdap_fasi_write_reg16 ( * struct i2c_device_addr *dev_addr, -- address of I2C device * u32 addr, -- address of chip register/memory * u16 data, -- data to send * u32 flags) -- special device flags * * Write one 16-bit register or memory location. The data being written is * converted from the target platform's endianness to little endian. * * Output: * - 0 if writing was successful * - -EIO if anything went wrong *
******************************/
/***************************** * * int drxdap_fasi_read_modify_write_reg16 ( * struct i2c_device_addr *dev_addr, -- address of I2C device * u32 waddr, -- address of chip register/memory * u32 raddr, -- chip address to read back from * u16 wdata, -- data to send * u16 *rdata) -- data to receive back * * Write 16-bit data, then read back the original contents of that location. * Requires long addressing format to be allowed. * * Before sending data, the data is converted to little endian. The * data received back is converted back to the target platform's endianness. * * WARNING: This function is only guaranteed to work if there is one * master on the I2C bus. * * Output: * - 0 if reading was successful * in that case: read back data is at *rdata * - -EIO if anything went wrong *
******************************/
/***************************** * * int drxdap_fasi_write_reg32 ( * struct i2c_device_addr *dev_addr, -- address of I2C device * u32 addr, -- address of chip register/memory * u32 data, -- data to send * u32 flags) -- special device flags * * Write one 32-bit register or memory location. The data being written is * converted from the target platform's endianness to little endian. * * Output: * - 0 if writing was successful * - -EIO if anything went wrong *
******************************/
/* * \fn int drxj_dap_rm_write_reg16short * \brief Read modify write 16 bits audio register using short format only. * \param dev_addr * \param waddr Address to write to * \param raddr Address to read from (usually SIO_HI_RA_RAM_S0_RMWBUF__A) * \param wdata Data to write * \param rdata Buffer for data to read * \return int * \retval 0 Success * \retval -EIO Timeout, I2C error, illegal bank * * 16 bits register read modify write access using short addressing format only. * Requires knowledge of the registermap, thus device dependent. * Using DAP FASI directly to avoid endless recursion of RMWs to audio registers. *
*/
/* TODO correct define should be #if ( DRXDAPFASI_SHORT_ADDR_ALLOWED==1 )
See comments drxj_dap_read_modify_write_reg16 */ #if (DRXDAPFASI_LONG_ADDR_ALLOWED == 0) staticint drxj_dap_rm_write_reg16short(struct i2c_device_addr *dev_addr,
u32 waddr,
u32 raddr,
u16 wdata, u16 *rdata)
{ int rc;
if (rdata == NULL) return -EINVAL;
/* Set RMW flag */
rc = drxdap_fasi_write_reg16(dev_addr,
SIO_HI_RA_RAM_S0_FLG_ACC__A,
SIO_HI_RA_RAM_S0_FLG_ACC_S0_RWM__M,
0x0000); if (rc == 0) { /* Write new data: triggers RMW */
rc = drxdap_fasi_write_reg16(dev_addr, waddr, wdata,
0x0000);
} if (rc == 0) { /* Read old data */
rc = drxdap_fasi_read_reg16(dev_addr, raddr, rdata,
0x0000);
} if (rc == 0) { /* Reset RMW flag */
rc = drxdap_fasi_write_reg16(dev_addr,
SIO_HI_RA_RAM_S0_FLG_ACC__A,
0, 0x0000);
}
/* * \fn int drxj_dap_read_aud_reg16 * \brief Read 16 bits audio register * \param dev_addr * \param addr * \param data * \return int * \retval 0 Success * \retval -EIO Timeout, I2C error, illegal bank * * 16 bits register read access via audio token ring interface. *
*/ staticint drxj_dap_read_aud_reg16(struct i2c_device_addr *dev_addr,
u32 addr, u16 *data)
{
u32 start_timer = 0;
u32 current_timer = 0;
u32 delta_timer = 0;
u16 tr_status = 0; int stat = -EIO;
/* No read possible for bank 3, return with error */ if (DRXDAP_FASI_ADDR2BANK(addr) == 3) {
stat = -EINVAL;
} else { const u32 write_bit = ((dr_xaddr_t) 1) << 16;
/* Force reset write bit */
addr &= (~write_bit);
/* Set up read */
start_timer = jiffies_to_msecs(jiffies); do { /* RMW to aud TR IF until request is granted or timeout */
stat = drxj_dap_read_modify_write_reg16(dev_addr,
addr,
SIO_HI_RA_RAM_S0_RMWBUF__A,
0x0000, &tr_status);
if (stat != 0) break;
current_timer = jiffies_to_msecs(jiffies);
delta_timer = current_timer - start_timer; if (delta_timer > DRXJ_DAP_AUDTRIF_TIMEOUT) {
stat = -EIO; break;
}
} while (((tr_status & AUD_TOP_TR_CTR_FIFO_LOCK__M) ==
AUD_TOP_TR_CTR_FIFO_LOCK_LOCKED) ||
((tr_status & AUD_TOP_TR_CTR_FIFO_FULL__M) ==
AUD_TOP_TR_CTR_FIFO_FULL_FULL));
} /* if ( DRXDAP_FASI_ADDR2BANK(addr)!=3 ) */
/* Wait for read ready status or timeout */ if (stat == 0) {
start_timer = jiffies_to_msecs(jiffies);
while ((tr_status & AUD_TOP_TR_CTR_FIFO_RD_RDY__M) !=
AUD_TOP_TR_CTR_FIFO_RD_RDY_READY) {
stat = drxj_dap_read_reg16(dev_addr,
AUD_TOP_TR_CTR__A,
&tr_status, 0x0000); if (stat != 0) break;
current_timer = jiffies_to_msecs(jiffies);
delta_timer = current_timer - start_timer; if (delta_timer > DRXJ_DAP_AUDTRIF_TIMEOUT) {
stat = -EIO; break;
}
} /* while ( ... ) */
}
/* Read value */ if (stat == 0)
stat = drxj_dap_read_modify_write_reg16(dev_addr,
AUD_TOP_TR_RD_REG__A,
SIO_HI_RA_RAM_S0_RMWBUF__A,
0x0000, data); return stat;
}
if (is_handled_by_aud_tr_if(addr))
stat = drxj_dap_read_aud_reg16(dev_addr, addr, data); else
stat = drxdap_fasi_read_reg16(dev_addr, addr, data, flags);
/* * \fn int drxj_dap_write_aud_reg16 * \brief Write 16 bits audio register * \param dev_addr * \param addr * \param data * \return int * \retval 0 Success * \retval -EIO Timeout, I2C error, illegal bank * * 16 bits register write access via audio token ring interface. *
*/ staticint drxj_dap_write_aud_reg16(struct i2c_device_addr *dev_addr,
u32 addr, u16 data)
{ int stat = -EIO;
/* No write possible for bank 2, return with error */ if (DRXDAP_FASI_ADDR2BANK(addr) == 2) {
stat = -EINVAL;
} else {
u32 start_timer = 0;
u32 current_timer = 0;
u32 delta_timer = 0;
u16 tr_status = 0; const u32 write_bit = ((dr_xaddr_t) 1) << 16;
/* Force write bit */
addr |= write_bit;
start_timer = jiffies_to_msecs(jiffies); do { /* RMW to aud TR IF until request is granted or timeout */
stat = drxj_dap_read_modify_write_reg16(dev_addr,
addr,
SIO_HI_RA_RAM_S0_RMWBUF__A,
data, &tr_status); if (stat != 0) break;
current_timer = jiffies_to_msecs(jiffies);
delta_timer = current_timer - start_timer; if (delta_timer > DRXJ_DAP_AUDTRIF_TIMEOUT) {
stat = -EIO; break;
}
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.77Bemerkung:
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.