Our ath5k IQ calibration computation seems to differ from the HALs.
Below is a userspace program which illustrates this better.

The regdump was from an AR5212. I have to test against more values.
Let me know if you see similar mismatches.

You can also wget this from:

http://ruslug.rutgers.edu/~mcgrof/tmp/iq.c

---
#include <stdio.h>
#include <sys/types.h>

#define AR5K_PHY_IQ_CORR_Q_I_COFF       0x000007e0
#define AR5K_PHY_IQ_CORR_Q_I_COFF_S     5
#define AR5K_PHY_IQ_CORR_Q_Q_COFF       0x0000001f
#define AR5K_PHY_IQ_CORR_ENABLE         0x00000800

/* This is what the AR5K_PHY_IQ register looks like to which we write
 * some final I and Q values to:
 *
 * 0000 0000   0000 0000   0000   0    000    000      0 0000
 * |---------------------| |----|  |  |------------|   |------|  
 *            ?              L     E         I            Q
 *
 * ? = Unknown
 * E = AR5K_PHY_IQ_CORR_ENABLE bit
 * L = AR5K_PHY_IQ_CAL_NUM_LOG_MAX (???)
 * I = Inphase, range seems to be 1 - 63
 * Q = Quadrature, range seems to be 1 - 31
 *
 * */

/* Implementation of I and Q calibration currently done in ath5k, this
 * doesn't seem to be right... */
int main(void) {
        u_int32_t i_pwr, q_pwr, val, final;
        int iq_corr, i_coff, i_coffd, q_coff, q_coffd;

        /* Current iq register value. This is just read to later append
         * our new I and Q values we want to write. */
        final = 0x7510ff08;

        /* Read from a register, the 'I power' */
        i_pwr = 0xf1366154;
        /* Read from a register, the 'Q power' */
        q_pwr = 0xe6f4851f;
        /* Read from a register, seem to be, 'I/Q Correlation' */
        iq_corr = 0x0f64d935;

        i_coffd = ((i_pwr >> 1) + (q_pwr >> 1)) >> 7;
        q_coffd = q_pwr >> 6;

        /* The AR5K_PHY_IQ_CORR_Q_I_COFF >> AR5K_PHY_IQ_CORR_Q_I_COFF_S is
         * done just to accomodate the values to be written to the right
         * place in the register for the I value */
        i_coff = ((-iq_corr) / i_coffd) &
                (AR5K_PHY_IQ_CORR_Q_I_COFF >> AR5K_PHY_IQ_CORR_Q_I_COFF_S);
        q_coff = (((int)i_pwr / q_coffd) - 64) & AR5K_PHY_IQ_CORR_Q_Q_COFF;

        /* Hex print, without the shift, these are the real values then
         * these seem to be negative values... */
        printf("Hex of actual values:\n");
        printf("i:\t0x%08x\n", ((-iq_corr) / i_coffd));
        printf("q:\t0x%08x\n", ((int)i_pwr / q_coffd) - 64);

        printf("Digit of actual values:\n");
        /* Digit print, of real values */
        printf("i:\t%d\n", ((-iq_corr) / i_coffd));
        printf("q:\t%d\n", ((int)i_pwr / q_coffd) - 64);

        /* Here's what -1 looks like in hex */
        printf("\n-1:\t0x%08x\n\n", -1);

        /* The actual currently computed value */
        printf("Currently computed values:\n");
        printf("i_coff:\t0x%08x\n", i_coff);
        printf("q_coff:\t0x%08x\n\n", q_coff);

        /* Final value we use to write to the AR5K_PHY_IQ register */
        val = AR5K_PHY_IQ_CORR_ENABLE |
                 ((u_int32_t)q_coff) | ((u_int32_t)i_coff << 
                        AR5K_PHY_IQ_CORR_Q_I_COFF_S);


        final |= val;

        printf("Final val we OR to the last read from AR5K_PHY_IQ:\n");
        printf("val:\t0x%08x\n\n", val);

        printf("Final val we write to AR5K_PHY_IQ\n"); 
        printf("final:\t0x%08x\n", final);

#if 0

Just so you get an idea, this is a regdump of what the HAL actually does:

R: Read
W: Write

This is the current value of AR5K_PHY_IQ
R:0x09920 = 0x7510ff08 - ath_hal_calibrate      AR5K_PHY_IQ

This is where where i_pwr and q_pwr are obtained from
R:0x09c10 = 0xf1366154 - ath_hal_calibrate      AR5K_PHY_IQRES_CAL_PWR_I
R:0x09c14 = 0xe6f4851f - ath_hal_calibrate      AR5K_PHY_IQRES_CAL_PWR_Q

This is where iq_corr is obtained from
R:0x09c18 = 0x0f64d935 - ath_hal_calibrate      AR5K_PHY_IQRES_CAL_CORR
R:0x09920 = 0x7510ff08 - ath_hal_calibrate      AR5K_PHY_IQ

This is what we end up writing to AR5K_PHY_IQ, note the values are different
from what we currently compute.
W:0x09920 = 0x7510f808 - ath_hal_calibrate      AR5K_PHY_IQ


Now this is what this program prints out. We're probably doing something
wrong...

Hex of actual values:
i:      0xfffffff8
q:      0xffffffbc
Digit of actual values:
i:      -8
q:      -68

-1:     0xffffffff

Currently computed values:
i_coff: 0x00000038
q_coff: 0x0000001c

Final val we OR to the last read from AR5K_PHY_IQ:
val:    0x00000f1c

Final val we write to AR5K_PHY_IQ
final:  0x7510ff1c

#endif 
        return 0;
}

_______________________________________________
ath5k-devel mailing list
ath5k-devel@lists.ath5k.org
https://lists.ath5k.org/mailman/listinfo/ath5k-devel

Reply via email to