view pirelli/rfcal @ 393:6c31d8c54ae4

se_k200i: preliminary analysis
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 06 Nov 2022 01:13:43 +0000
parents 2cc7a17c3859
children
line wrap: on
line source

The 64 KiB flash sector at 0x027F0000 (the last sector of the 2nd flash bank)
contains per-unit factory data, including the IMEI and RF calibration values.
The location of the IMEI record (at offset 0x504) was found back in 2013-07 and
its encryption was figured out in 2013-11, but it took a bit longer to find the
RF calibration data.  Most of the RF calibration bits were found in 2014-07,
but the complete picture presented below has only been reconstructed in 2017-11.

The data structure corresponding to TI's RF calibration files listed in the
config_files_common[] and config_files_band[] arrays in l1_cust.c begins at
offset 0x528, and has space allocated for each and every one of the files
listed in those arrays in TI's canonical version, in the same order as in that
canonical version, with the single exception of /sys/uartswitch.  Behold:

Hex offset	Corresponding FFS file in TI's canonical version
----------------------------------------------------------------
0528		/gsm/rf/afcdac
052A		    checksum byte
052B		442 (0x1BA) unused (all FF) bytes making room for:
		    /gsm/rf/stdmap
		    /gsm/rf/afcparams
		    /gsm/rf/rx/agcglobals
		    /gsm/rf/rx/il2agc
		    /gsm/rf/rx/agcwords

06E5		/sys/adccal
0709		    checksum byte
070A		33 (0x21) unused (all FF) bytes making room for:
		    /sys/abb

072B		/gsm/rf/tx/ramps.900
092B		    checksum byte
092C		/gsm/rf/tx/levels.900
09AC		    checksum byte
09AD		/gsm/rf/tx/calchan.900
0A2D		    checksum byte
0A2E		/gsm/rf/tx/ramps.1800
0C2E		    checksum byte
0C2F		/gsm/rf/tx/levels.1800
0CAF		    checksum byte
0CB0		/gsm/rf/tx/calchan.1800
0D30		    checksum byte
0D31		/gsm/rf/tx/ramps.1900
0F31		    checksum byte
0F32		/gsm/rf/tx/levels.1900
0FB2		    checksum byte
0FB3		/gsm/rf/tx/calchan.1900
1033		    checksum byte
1034		123 (0x7B) unused (all FF) bytes making room for:
		    /gsm/rf/tx/caltemp.900
		    /gsm/rf/tx/caltemp.1800
		    /gsm/rf/tx/caltemp.1900

10AF		/gsm/rf/rx/calchan.900
10D7		    checksum byte
10D8		/gsm/rf/rx/agcparams.900
10E0		    checksum byte
10E1		/gsm/rf/rx/calchan.1800
1109		    checksum byte
110A		/gsm/rf/rx/agcparams.1800
1112		    checksum byte
1113		/gsm/rf/rx/calchan.1900
113B		    checksum byte
113C		/gsm/rf/rx/agcparams.1900
1144		    checksum byte
1145		more than enough unused (all FF) bytes to fit:
		    /gsm/rf/rx/caltemp.900
		    /gsm/rf/rx/caltemp.1800
		    /gsm/rf/rx/caltemp.1900

TI's canonical version classifies each of the files listed in those
config_files_common[] and config_files_band[] arrays into one of 8 categories:

f = RF calibration
F = RF config
r = Rx calibration
R = Rx config
t = Tx calibration
T = Tx config
s = system calibration
S = system config

Pirelli's factory data structure allocates space for all of the possible files
in all 8 categories, but out of all these spaces, the only ones that are
actually filled with bits (not all FF) are the ones corresponding to the 4
"calibration" categories, and not the "config" ones.  It is my (Mychaela's)
guess that Foxconn folks probably preserved the logic invoked by me 102 through
me 109 commands unchanged from TI's original, and thus had the theoretical
ability to write everything into their invented data structure, but only issued
the me 102/104/106/108 commands in their factory production flow, hence only
the "calibration" record slots got filled.

Please note that the slots corresponding to the missing files in the "config"
categories are filled with all FF bytes, and do NOT contain the "standard" or
"never changed" bits compiled into the firmware.  Because these bits are not
present in the factory record in the flash, any aftermarket firmware running on
these phones needs to provide these bits on its own.  This category very notably
includes the afcparams table.

Each calibration record is followed by a checksum byte.  It is a simple ripple-
carry sum of all bytes in the preceding record.  Note that this checksum byte
is always 0 for the ramps records, as each correctly-formed ramp adds up to 128
(0x80), and the array has an even number of ramps in total.  It is also my
(Mychaela's) guess that Pirelli's fw probably uses this checksum byte to detect
that the "config" files are missing and avoid loading the FF bytes into the
corresponding L1 RAM data structures: the sum of all FF bytes in the data space
does not equal FF unless the record length is 1 byte or 257 or 513... bytes,
and none of TI's calibration/config records match those byte lengths.

Absence of the afcparams table
==============================

The afcparams table is placed in the "RF config" category in TI's TCS211
reference fw, rather than "RF calibration".  It appears that in the very old
days of Sara RF (before the D-Sample) this table contained only the Psi
constants (no min/max/nominal DAC), and these Psi constants were tweaked in the
source code in l1_rfN.h, rather than via per-unit calibration - hence the
"config" rather than "calibration" classification.  Then RF 10 (Clara) came
along, TI started using "plain" VCXOs without the "TC" part, they implemented a
new AFC algorithm (VCXO_ALGO), and the min/max/nominal DAC fields got added to
the afcparams table.  The complete story is not clear, but the end result is
that when the days of Openmoko came around, FIC (OM's factory) had a production
line calibration program, presumably from TI (I never got a copy of it, but I
was told it was a Windows binary sans source), that performed individual
per-unit calibration of the VCXO along with the expected Rx and Tx band
calibrations, and the afcparams table is calibrated per unit on Openmoko
devices.

Both theory and practice indicate that OM's way of calibrating the afcparams
table on a per-unit basis is not the only way: the per-unit calibration does
not help much in practice because of the strong temperature sensitivity, and
the new AFC algorithm implemented by TI has to deal with wide uncertainties in
the initial VCXO frequency.  Instead it appears to be sufficient to calibrate
the VCXO and the settings in the afcparams table on a per-design basis, rather
than per unit, and it appears that Motorola/Compal did just that on their C1xx
phones - which use a "plain" VCXO and not a VCTCXO like the Pirelli.

Querying Pirelli's fw for the actively used afcparams table via rftr 9 returns
the following:

rf_table afcparams

      6974	# psi_sta_inv
         8	# psi_st
    492713	# psi_st_32
      8717	# psi_st_inv

       888	# dac_center
     -9568	# dac_min
     11352	# dac_max
      2560	# snr_thr

Because the slot in the factory data structure where the afcparams record ought
to go is all FF bytes, the table returned by the fw above can only be hard-coded
in the fw itself.  The 4 numbers in the second group are exactly the same as
the hard-coded numbers in l1_rf12.h in TI's reference fw, but the Psi numbers
are different - Foxconn/Pirelli folks must have tuned them for their VCTCXO.

In this light, it is worthy to note that the afcdac record *is* present in
Pirelli's factory data block, and it differs from one unit to the next, i.e.,
it has been calibrated on a per-unit basis.  TI's reference fw selects the
ALGO_AFC_LQG_PREDICTOR AFC algorithm which does not use this afcdac setting
at all, but perhaps Pirelli's fw does something different because of their use
of a VCTCXO instead of a "plain" VCXO - we don't know, and the reverse eng
effort to find the needed answers would be more than we can currently justify.