2 * phy_302_calibration.c
4 * Copyright (C) 2002, 2005 Winbond Electronics Corp.
7 * ---------------------------------------------------------------------------
8 * 0.01.001, 2003-04-16, Kevin created
12 /****************** INCLUDE FILES SECTION ***********************************/
13 #include "os_common.h"
14 #include "phy_calibration.h"
17 /****************** DEBUG CONSTANT AND MACRO SECTION ************************/
19 /****************** LOCAL CONSTANT AND MACRO SECTION ************************/
21 #define US 1000//MICROSECOND
23 #define AG_CONST 0.6072529350
24 #define FIXED(X) ((s32)((X) * 32768.0))
25 #define DEG2RAD(X) 0.017453 * (X)
27 /****************** LOCAL TYPE DEFINITION SECTION ***************************/
28 typedef s32 fixed
; /* 16.16 fixed-point */
30 static const fixed Angles
[]=
32 FIXED(DEG2RAD(45.0)), FIXED(DEG2RAD(26.565)), FIXED(DEG2RAD(14.0362)),
33 FIXED(DEG2RAD(7.12502)), FIXED(DEG2RAD(3.57633)), FIXED(DEG2RAD(1.78991)),
34 FIXED(DEG2RAD(0.895174)),FIXED(DEG2RAD(0.447614)),FIXED(DEG2RAD(0.223811)),
35 FIXED(DEG2RAD(0.111906)),FIXED(DEG2RAD(0.055953)),FIXED(DEG2RAD(0.027977))
38 /****************** LOCAL FUNCTION DECLARATION SECTION **********************/
39 //void _phy_rf_write_delay(hw_data_t *phw_data);
40 //void phy_init_rf(hw_data_t *phw_data);
42 /****************** FUNCTION DEFINITION SECTION *****************************/
44 s32
_s13_to_s32(u32 data
)
48 val
= (data
& 0x0FFF);
50 if ((data
& BIT(12)) != 0)
58 u32
_s32_to_s13(s32 data
)
66 else if (data
< -4096)
76 /****************************************************************************/
77 s32
_s4_to_s32(u32 data
)
81 val
= (data
& 0x0007);
83 if ((data
& BIT(3)) != 0)
91 u32
_s32_to_s4(s32 data
)
109 /****************************************************************************/
110 s32
_s5_to_s32(u32 data
)
114 val
= (data
& 0x000F);
116 if ((data
& BIT(4)) != 0)
124 u32
_s32_to_s5(s32 data
)
142 /****************************************************************************/
143 s32
_s6_to_s32(u32 data
)
147 val
= (data
& 0x001F);
149 if ((data
& BIT(5)) != 0)
157 u32
_s32_to_s6(s32 data
)
175 /****************************************************************************/
176 s32
_s9_to_s32(u32 data
)
182 if ((data
& BIT(8)) != 0)
190 u32
_s32_to_s9(s32 data
)
198 else if (data
< -256)
208 /****************************************************************************/
223 /****************************************************************************/
224 // The following code is sqare-root function.
225 // sqsum is the input and the output is sq_rt;
226 // The maximum of sqsum = 2^27 -1;
231 int g0
, g1
, g2
, g3
, g4
;
236 g4
= sqsum
/ 100000000;
237 g3
= (sqsum
- g4
*100000000) /1000000;
238 g2
= (sqsum
- g4
*100000000 - g3
*1000000) /10000;
239 g1
= (sqsum
- g4
*100000000 - g3
*1000000 - g2
*10000) /100;
240 g0
= (sqsum
- g4
*100000000 - g3
*1000000 - g2
*10000 - g1
*100);
245 while (((seed
+1)*(step
+1)) <= next
)
251 sq_rt
= seed
* 10000;
252 next
= (next
-(seed
*step
))*100 + g3
;
255 seed
= 2 * seed
* 10;
256 while (((seed
+1)*(step
+1)) <= next
)
262 sq_rt
= sq_rt
+ step
* 1000;
263 next
= (next
- seed
* step
) * 100 + g2
;
264 seed
= (seed
+ step
) * 10;
266 while (((seed
+1)*(step
+1)) <= next
)
272 sq_rt
= sq_rt
+ step
* 100;
273 next
= (next
- seed
* step
) * 100 + g1
;
274 seed
= (seed
+ step
) * 10;
277 while (((seed
+1)*(step
+1)) <= next
)
283 sq_rt
= sq_rt
+ step
* 10;
284 next
= (next
- seed
* step
) * 100 + g0
;
285 seed
= (seed
+ step
) * 10;
288 while (((seed
+1)*(step
+1)) <= next
)
294 sq_rt
= sq_rt
+ step
;
299 /****************************************************************************/
300 void _sin_cos(s32 angle
, s32
*sin
, s32
*cos
)
302 fixed X
, Y
, TargetAngle
, CurrAngle
;
305 X
=FIXED(AG_CONST
); // AG_CONST * cos(0)
306 Y
=0; // AG_CONST * sin(0)
307 TargetAngle
=abs(angle
);
310 for (Step
=0; Step
< 12; Step
++)
314 if(TargetAngle
> CurrAngle
)
316 NewX
=X
- (Y
>> Step
);
319 CurrAngle
+= Angles
[Step
];
323 NewX
=X
+ (Y
>> Step
);
326 CurrAngle
-= Angles
[Step
];
343 void _reset_rx_cal(hw_data_t
*phw_data
)
347 hw_get_dxx_reg(phw_data
, 0x54, &val
);
349 if (phw_data
->revision
== 0x2002) // 1st-cut
358 hw_set_dxx_reg(phw_data
, 0x54, val
);
362 // ************for winbond calibration*********
367 // *********************************************
368 void _rxadc_dc_offset_cancellation_winbond(hw_data_t
*phw_data
, u32 frequency
)
375 PHY_DEBUG(("[CAL] -> [1]_rxadc_dc_offset_cancellation()\n"));
376 phy_init_rf(phw_data
);
378 // set calibration channel
379 if( (RF_WB_242
== phw_data
->phy_type
) ||
380 (RF_WB_242_1
== phw_data
->phy_type
) ) // 20060619.5 Add
382 if ((frequency
>= 2412) && (frequency
<= 2484))
384 // w89rf242 change frequency to 2390Mhz
385 PHY_DEBUG(("[CAL] W89RF242/11G/Channel=2390Mhz\n"));
386 phy_set_rf_data(phw_data
, 3, (3<<24)|0x025586);
395 // reset cancel_dc_i[9:5] and cancel_dc_q[4:0] in register DC_Cancel
396 hw_get_dxx_reg(phw_data
, 0x5C, &val
);
398 hw_set_dxx_reg(phw_data
, 0x5C, val
);
400 // reset the TX and RX IQ calibration data
401 hw_set_dxx_reg(phw_data
, 0x3C, 0);
402 hw_set_dxx_reg(phw_data
, 0x54, 0);
404 hw_set_dxx_reg(phw_data
, 0x58, 0x30303030); // IQ_Alpha Changed
407 hw_get_dxx_reg(phw_data
, REG_AGC_CTRL3
, ®_agc_ctrl3
);
408 reg_agc_ctrl3
&= ~BIT(2);
409 reg_agc_ctrl3
|= (MASK_LNA_FIX_GAIN
|MASK_AGC_FIX
);
410 hw_set_dxx_reg(phw_data
, REG_AGC_CTRL3
, reg_agc_ctrl3
);
412 hw_get_dxx_reg(phw_data
, REG_AGC_CTRL5
, &val
);
413 val
|= MASK_AGC_FIX_GAIN
;
414 hw_set_dxx_reg(phw_data
, REG_AGC_CTRL5
, val
);
417 hw_get_dxx_reg(phw_data
, REG_A_ACQ_CTRL
, ®_a_acq_ctrl
);
418 reg_a_acq_ctrl
|= MASK_AMER_OFF_REG
;
419 hw_set_dxx_reg(phw_data
, REG_A_ACQ_CTRL
, reg_a_acq_ctrl
);
421 hw_get_dxx_reg(phw_data
, REG_B_ACQ_CTRL
, ®_b_acq_ctrl
);
422 reg_b_acq_ctrl
|= MASK_BMER_OFF_REG
;
423 hw_set_dxx_reg(phw_data
, REG_B_ACQ_CTRL
, reg_b_acq_ctrl
);
425 // c. Make sure MAC is in receiving mode
426 // d. Turn ON ADC calibration
427 // - ADC calibrator is triggered by this signal rising from 0 to 1
428 hw_get_dxx_reg(phw_data
, REG_MODE_CTRL
, &val
);
429 val
&= ~MASK_ADC_DC_CAL_STR
;
430 hw_set_dxx_reg(phw_data
, REG_MODE_CTRL
, val
);
432 val
|= MASK_ADC_DC_CAL_STR
;
433 hw_set_dxx_reg(phw_data
, REG_MODE_CTRL
, val
);
434 pa_stall_execution(US
); // *MUST* wait for a while
436 // e. The result are shown in "adc_dc_cal_i[8:0] and adc_dc_cal_q[8:0]"
438 hw_get_dxx_reg(phw_data
, REG_OFFSET_READ
, &val
);
439 PHY_DEBUG(("[CAL] REG_OFFSET_READ = 0x%08X\n", val
));
441 PHY_DEBUG(("[CAL] ** adc_dc_cal_i = %d (0x%04X)\n",
442 _s9_to_s32(val
&0x000001FF), val
&0x000001FF));
443 PHY_DEBUG(("[CAL] ** adc_dc_cal_q = %d (0x%04X)\n",
444 _s9_to_s32((val
&0x0003FE00)>>9), (val
&0x0003FE00)>>9));
447 hw_get_dxx_reg(phw_data
, REG_MODE_CTRL
, &val
);
448 val
&= ~MASK_ADC_DC_CAL_STR
;
449 hw_set_dxx_reg(phw_data
, REG_MODE_CTRL
, val
);
452 //hw_get_dxx_reg(phw_data, REG_A_ACQ_CTRL, ®_a_acq_ctrl);
453 reg_a_acq_ctrl
&= ~MASK_AMER_OFF_REG
;
454 hw_set_dxx_reg(phw_data
, REG_A_ACQ_CTRL
, reg_a_acq_ctrl
);
456 //hw_get_dxx_reg(phw_data, REG_B_ACQ_CTRL, ®_b_acq_ctrl);
457 reg_b_acq_ctrl
&= ~MASK_BMER_OFF_REG
;
458 hw_set_dxx_reg(phw_data
, REG_B_ACQ_CTRL
, reg_b_acq_ctrl
);
461 //hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, &val);
462 reg_agc_ctrl3
|= BIT(2);
463 reg_agc_ctrl3
&= ~(MASK_LNA_FIX_GAIN
|MASK_AGC_FIX
);
464 hw_set_dxx_reg(phw_data
, REG_AGC_CTRL3
, reg_agc_ctrl3
);
467 ////////////////////////////////////////////////////////
468 void _txidac_dc_offset_cancellation_winbond(hw_data_t
*phw_data
)
478 s32 fix_cancel_dc_i
= 0;
482 PHY_DEBUG(("[CAL] -> [2]_txidac_dc_offset_cancellation()\n"));
484 // a. Set to "TX calibration mode"
486 //0x01 0xEE3FC2 ; 3B8FF ; Calibration (6a). enable TX IQ calibration loop circuits
487 phy_set_rf_data(phw_data
, 1, (1<<24)|0xEE3FC2);
488 //0x0B 0x1905D6 ; 06417 ; Calibration (6b). enable TX I/Q cal loop squaring circuit
489 phy_set_rf_data(phw_data
, 11, (11<<24)|0x1901D6);
490 //0x05 0x24C60A ; 09318 ; Calibration (6c). setting TX-VGA gain: TXGCH=2 & GPK=110 --> to be optimized
491 phy_set_rf_data(phw_data
, 5, (5<<24)|0x24C48A);
492 //0x06 0x06880C ; 01A20 ; Calibration (6d). RXGCH=00; RXGCL=100 000 (RXVGA=32) --> to be optimized
493 phy_set_rf_data(phw_data
, 6, (6<<24)|0x06890C);
494 //0x00 0xFDF1C0 ; 3F7C7 ; Calibration (6e). turn on IQ imbalance/Test mode
495 phy_set_rf_data(phw_data
, 0, (0<<24)|0xFDF1C0);
497 hw_set_dxx_reg(phw_data
, 0x58, 0x30303030); // IQ_Alpha Changed
500 hw_get_dxx_reg(phw_data
, REG_AGC_CTRL3
, ®_agc_ctrl3
);
501 reg_agc_ctrl3
&= ~BIT(2);
502 reg_agc_ctrl3
|= (MASK_LNA_FIX_GAIN
|MASK_AGC_FIX
);
503 hw_set_dxx_reg(phw_data
, REG_AGC_CTRL3
, reg_agc_ctrl3
);
505 hw_get_dxx_reg(phw_data
, REG_AGC_CTRL5
, &val
);
506 val
|= MASK_AGC_FIX_GAIN
;
507 hw_set_dxx_reg(phw_data
, REG_AGC_CTRL5
, val
);
509 // b. set iqcal_mode[1:0] to 0x2 and set iqcal_tone[3:2] to 0
510 hw_get_dxx_reg(phw_data
, REG_MODE_CTRL
, ®_mode_ctrl
);
512 PHY_DEBUG(("[CAL] MODE_CTRL (read) = 0x%08X\n", reg_mode_ctrl
));
513 reg_mode_ctrl
&= ~(MASK_IQCAL_TONE_SEL
|MASK_IQCAL_MODE
);
516 //reg_mode_ctrl |= (MASK_CALIB_START|2);
519 //reg_mode_ctrl |= (MASK_CALIB_START|2|(1<<2));
522 reg_mode_ctrl
|= (MASK_CALIB_START
|2|(2<<2));
523 hw_set_dxx_reg(phw_data
, REG_MODE_CTRL
, reg_mode_ctrl
);
524 PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl
));
525 pa_stall_execution(US
);
527 hw_get_dxx_reg(phw_data
, 0x5C, ®_dc_cancel
);
528 PHY_DEBUG(("[CAL] DC_CANCEL (read) = 0x%08X\n", reg_dc_cancel
));
530 for (loop
= 0; loop
< LOOP_TIMES
; loop
++)
532 PHY_DEBUG(("[CAL] [%d.] ==================================\n", loop
));
535 // reset cancel_dc_i[9:5] and cancel_dc_q[4:0] in register DC_Cancel
536 reg_dc_cancel
&= ~(0x03FF);
537 PHY_DEBUG(("[CAL] DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel
));
538 hw_set_dxx_reg(phw_data
, 0x5C, reg_dc_cancel
);
539 pa_stall_execution(US
);
541 hw_get_dxx_reg(phw_data
, REG_CALIB_READ2
, &val
);
542 PHY_DEBUG(("[CAL] CALIB_READ2 = 0x%08X\n", val
));
544 iqcal_image_i
= _s13_to_s32(val
& 0x00001FFF);
545 iqcal_image_q
= _s13_to_s32((val
& 0x03FFE000) >> 13);
546 sqsum
= iqcal_image_i
*iqcal_image_i
+ iqcal_image_q
*iqcal_image_q
;
547 mag_0
= (s32
) _sqrt(sqsum
);
548 PHY_DEBUG(("[CAL] mag_0=%d (iqcal_image_i=%d, iqcal_image_q=%d)\n",
549 mag_0
, iqcal_image_i
, iqcal_image_q
));
552 reg_dc_cancel
|= (1 << CANCEL_DC_I_SHIFT
);
553 PHY_DEBUG(("[CAL] DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel
));
554 hw_set_dxx_reg(phw_data
, 0x5C, reg_dc_cancel
);
555 pa_stall_execution(US
);
557 hw_get_dxx_reg(phw_data
, REG_CALIB_READ2
, &val
);
558 PHY_DEBUG(("[CAL] CALIB_READ2 = 0x%08X\n", val
));
560 iqcal_image_i
= _s13_to_s32(val
& 0x00001FFF);
561 iqcal_image_q
= _s13_to_s32((val
& 0x03FFE000) >> 13);
562 sqsum
= iqcal_image_i
*iqcal_image_i
+ iqcal_image_q
*iqcal_image_q
;
563 mag_1
= (s32
) _sqrt(sqsum
);
564 PHY_DEBUG(("[CAL] mag_1=%d (iqcal_image_i=%d, iqcal_image_q=%d)\n",
565 mag_1
, iqcal_image_i
, iqcal_image_q
));
567 // e. Calculate the correct DC offset cancellation value for I
570 fix_cancel_dc_i
= (mag_0
*10000) / (mag_0
*10000 - mag_1
*10000);
576 PHY_DEBUG(("[CAL] ***** mag_0 = mag_1 !!\n"));
582 PHY_DEBUG(("[CAL] ** fix_cancel_dc_i = %d (0x%04X)\n",
583 fix_cancel_dc_i
, _s32_to_s5(fix_cancel_dc_i
)));
585 if ((abs(mag_1
-mag_0
)*6) > mag_0
)
594 reg_dc_cancel
&= ~(0x03FF);
595 reg_dc_cancel
|= (_s32_to_s5(fix_cancel_dc_i
) << CANCEL_DC_I_SHIFT
);
596 hw_set_dxx_reg(phw_data
, 0x5C, reg_dc_cancel
);
597 PHY_DEBUG(("[CAL] DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel
));
600 reg_mode_ctrl
&= ~MASK_CALIB_START
;
601 hw_set_dxx_reg(phw_data
, REG_MODE_CTRL
, reg_mode_ctrl
);
602 PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl
));
603 pa_stall_execution(US
);
606 ///////////////////////////////////////////////////////
607 void _txqdac_dc_offset_cacellation_winbond(hw_data_t
*phw_data
)
617 s32 fix_cancel_dc_q
= 0;
621 PHY_DEBUG(("[CAL] -> [3]_txqdac_dc_offset_cacellation()\n"));
622 //0x01 0xEE3FC2 ; 3B8FF ; Calibration (6a). enable TX IQ calibration loop circuits
623 phy_set_rf_data(phw_data
, 1, (1<<24)|0xEE3FC2);
624 //0x0B 0x1905D6 ; 06417 ; Calibration (6b). enable TX I/Q cal loop squaring circuit
625 phy_set_rf_data(phw_data
, 11, (11<<24)|0x1901D6);
626 //0x05 0x24C60A ; 09318 ; Calibration (6c). setting TX-VGA gain: TXGCH=2 & GPK=110 --> to be optimized
627 phy_set_rf_data(phw_data
, 5, (5<<24)|0x24C48A);
628 //0x06 0x06880C ; 01A20 ; Calibration (6d). RXGCH=00; RXGCL=100 000 (RXVGA=32) --> to be optimized
629 phy_set_rf_data(phw_data
, 6, (6<<24)|0x06890C);
630 //0x00 0xFDF1C0 ; 3F7C7 ; Calibration (6e). turn on IQ imbalance/Test mode
631 phy_set_rf_data(phw_data
, 0, (0<<24)|0xFDF1C0);
633 hw_set_dxx_reg(phw_data
, 0x58, 0x30303030); // IQ_Alpha Changed
636 hw_get_dxx_reg(phw_data
, REG_AGC_CTRL3
, ®_agc_ctrl3
);
637 reg_agc_ctrl3
&= ~BIT(2);
638 reg_agc_ctrl3
|= (MASK_LNA_FIX_GAIN
|MASK_AGC_FIX
);
639 hw_set_dxx_reg(phw_data
, REG_AGC_CTRL3
, reg_agc_ctrl3
);
641 hw_get_dxx_reg(phw_data
, REG_AGC_CTRL5
, &val
);
642 val
|= MASK_AGC_FIX_GAIN
;
643 hw_set_dxx_reg(phw_data
, REG_AGC_CTRL5
, val
);
645 // a. set iqcal_mode[1:0] to 0x3 and set iqcal_tone[3:2] to 0
646 hw_get_dxx_reg(phw_data
, REG_MODE_CTRL
, ®_mode_ctrl
);
647 PHY_DEBUG(("[CAL] MODE_CTRL (read) = 0x%08X\n", reg_mode_ctrl
));
649 //reg_mode_ctrl &= ~(MASK_IQCAL_TONE_SEL|MASK_IQCAL_MODE);
650 reg_mode_ctrl
&= ~(MASK_IQCAL_MODE
);
651 reg_mode_ctrl
|= (MASK_CALIB_START
|3);
652 hw_set_dxx_reg(phw_data
, REG_MODE_CTRL
, reg_mode_ctrl
);
653 PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl
));
654 pa_stall_execution(US
);
656 hw_get_dxx_reg(phw_data
, 0x5C, ®_dc_cancel
);
657 PHY_DEBUG(("[CAL] DC_CANCEL (read) = 0x%08X\n", reg_dc_cancel
));
659 for (loop
= 0; loop
< LOOP_TIMES
; loop
++)
661 PHY_DEBUG(("[CAL] [%d.] ==================================\n", loop
));
664 // reset cancel_dc_q[4:0] in register DC_Cancel
665 reg_dc_cancel
&= ~(0x001F);
666 PHY_DEBUG(("[CAL] DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel
));
667 hw_set_dxx_reg(phw_data
, 0x5C, reg_dc_cancel
);
668 pa_stall_execution(US
);
670 hw_get_dxx_reg(phw_data
, REG_CALIB_READ2
, &val
);
671 PHY_DEBUG(("[CAL] CALIB_READ2 = 0x%08X\n", val
));
672 pa_stall_execution(US
);
674 iqcal_image_i
= _s13_to_s32(val
& 0x00001FFF);
675 iqcal_image_q
= _s13_to_s32((val
& 0x03FFE000) >> 13);
676 sqsum
= iqcal_image_i
*iqcal_image_i
+ iqcal_image_q
*iqcal_image_q
;
677 mag_0
= _sqrt(sqsum
);
678 PHY_DEBUG(("[CAL] mag_0=%d (iqcal_image_i=%d, iqcal_image_q=%d)\n",
679 mag_0
, iqcal_image_i
, iqcal_image_q
));
682 reg_dc_cancel
|= (1 << CANCEL_DC_Q_SHIFT
);
683 PHY_DEBUG(("[CAL] DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel
));
684 hw_set_dxx_reg(phw_data
, 0x5C, reg_dc_cancel
);
685 pa_stall_execution(US
);
687 hw_get_dxx_reg(phw_data
, REG_CALIB_READ2
, &val
);
688 PHY_DEBUG(("[CAL] CALIB_READ2 = 0x%08X\n", val
));
689 pa_stall_execution(US
);
691 iqcal_image_i
= _s13_to_s32(val
& 0x00001FFF);
692 iqcal_image_q
= _s13_to_s32((val
& 0x03FFE000) >> 13);
693 sqsum
= iqcal_image_i
*iqcal_image_i
+ iqcal_image_q
*iqcal_image_q
;
694 mag_1
= _sqrt(sqsum
);
695 PHY_DEBUG(("[CAL] mag_1=%d (iqcal_image_i=%d, iqcal_image_q=%d)\n",
696 mag_1
, iqcal_image_i
, iqcal_image_q
));
698 // d. Calculate the correct DC offset cancellation value for I
701 fix_cancel_dc_q
= (mag_0
*10000) / (mag_0
*10000 - mag_1
*10000);
707 PHY_DEBUG(("[CAL] ***** mag_0 = mag_1 !!\n"));
713 PHY_DEBUG(("[CAL] ** fix_cancel_dc_q = %d (0x%04X)\n",
714 fix_cancel_dc_q
, _s32_to_s5(fix_cancel_dc_q
)));
716 if ((abs(mag_1
-mag_0
)*6) > mag_0
)
725 reg_dc_cancel
&= ~(0x001F);
726 reg_dc_cancel
|= (_s32_to_s5(fix_cancel_dc_q
) << CANCEL_DC_Q_SHIFT
);
727 hw_set_dxx_reg(phw_data
, 0x5C, reg_dc_cancel
);
728 PHY_DEBUG(("[CAL] DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel
));
732 reg_mode_ctrl
&= ~MASK_CALIB_START
;
733 hw_set_dxx_reg(phw_data
, REG_MODE_CTRL
, reg_mode_ctrl
);
734 PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl
));
735 pa_stall_execution(US
);
738 //20060612.1.a 20060718.1 Modify
739 u8
_tx_iq_calibration_loop_winbond(hw_data_t
*phw_data
,
762 s32 iqcal_tone_i_avg
,iqcal_tone_q_avg
;
766 PHY_DEBUG(("[CAL] -> _tx_iq_calibration_loop()\n"));
767 PHY_DEBUG(("[CAL] ** a_2_threshold = %d\n", a_2_threshold
));
768 PHY_DEBUG(("[CAL] ** b_2_threshold = %d\n", b_2_threshold
));
772 hw_get_dxx_reg(phw_data
, REG_MODE_CTRL
, ®_mode_ctrl
);
773 PHY_DEBUG(("[CAL] MODE_CTRL (read) = 0x%08X\n", reg_mode_ctrl
));
779 PHY_DEBUG(("[CAL] [%d.] <_tx_iq_calibration_loop>\n", (LOOP_TIMES
-loop
+1)));
783 if( !hw_set_dxx_reg(phw_data
, 0x3C, 0x00) ) // 20060718.1 modify
785 for(capture_time
=0;capture_time
<10;capture_time
++)
787 // a. Set iqcal_mode[1:0] to 0x2 and set "calib_start" to 0x1 to
788 // enable "IQ alibration Mode II"
789 reg_mode_ctrl
&= ~(MASK_IQCAL_TONE_SEL
|MASK_IQCAL_MODE
);
790 reg_mode_ctrl
&= ~MASK_IQCAL_MODE
;
791 reg_mode_ctrl
|= (MASK_CALIB_START
|0x02);
792 reg_mode_ctrl
|= (MASK_CALIB_START
|0x02|2<<2);
793 hw_set_dxx_reg(phw_data
, REG_MODE_CTRL
, reg_mode_ctrl
);
794 PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl
));
795 pa_stall_execution(US
);
798 hw_get_dxx_reg(phw_data
, REG_CALIB_READ1
, &val
);
799 PHY_DEBUG(("[CAL] CALIB_READ1 = 0x%08X\n", val
));
800 pa_stall_execution(US
);
802 iqcal_tone_i0
= _s13_to_s32(val
& 0x00001FFF);
803 iqcal_tone_q0
= _s13_to_s32((val
& 0x03FFE000) >> 13);
804 PHY_DEBUG(("[CAL] ** iqcal_tone_i0=%d, iqcal_tone_q0=%d\n",
805 iqcal_tone_i0
, iqcal_tone_q0
));
807 sqsum
= iqcal_tone_i0
*iqcal_tone_i0
+
808 iqcal_tone_q0
*iqcal_tone_q0
;
809 iq_mag_0_tx
= (s32
) _sqrt(sqsum
);
810 PHY_DEBUG(("[CAL] ** iq_mag_0_tx=%d\n", iq_mag_0_tx
));
812 // c. Set "calib_start" to 0x0
813 reg_mode_ctrl
&= ~MASK_CALIB_START
;
814 hw_set_dxx_reg(phw_data
, REG_MODE_CTRL
, reg_mode_ctrl
);
815 PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl
));
816 pa_stall_execution(US
);
818 // d. Set iqcal_mode[1:0] to 0x3 and set "calib_start" to 0x1 to
819 // enable "IQ alibration Mode II"
820 //hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &val);
821 hw_get_dxx_reg(phw_data
, REG_MODE_CTRL
, ®_mode_ctrl
);
822 reg_mode_ctrl
&= ~MASK_IQCAL_MODE
;
823 reg_mode_ctrl
|= (MASK_CALIB_START
|0x03);
824 hw_set_dxx_reg(phw_data
, REG_MODE_CTRL
, reg_mode_ctrl
);
825 PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl
));
826 pa_stall_execution(US
);
829 hw_get_dxx_reg(phw_data
, REG_CALIB_READ1
, &val
);
830 PHY_DEBUG(("[CAL] CALIB_READ1 = 0x%08X\n", val
));
831 pa_stall_execution(US
);
833 iqcal_tone_i
= _s13_to_s32(val
& 0x00001FFF);
834 iqcal_tone_q
= _s13_to_s32((val
& 0x03FFE000) >> 13);
835 PHY_DEBUG(("[CAL] ** iqcal_tone_i = %d, iqcal_tone_q = %d\n",
836 iqcal_tone_i
, iqcal_tone_q
));
837 if( capture_time
== 0)
843 iqcal_tone_i_avg
=( iqcal_tone_i_avg
*(capture_time
-1) +iqcal_tone_i
)/capture_time
;
844 iqcal_tone_q_avg
=( iqcal_tone_q_avg
*(capture_time
-1) +iqcal_tone_q
)/capture_time
;
848 iqcal_tone_i
= iqcal_tone_i_avg
;
849 iqcal_tone_q
= iqcal_tone_q_avg
;
852 rot_i_b
= (iqcal_tone_i
* iqcal_tone_i0
+
853 iqcal_tone_q
* iqcal_tone_q0
) / 1024;
854 rot_q_b
= (iqcal_tone_i
* iqcal_tone_q0
* (-1) +
855 iqcal_tone_q
* iqcal_tone_i0
) / 1024;
856 PHY_DEBUG(("[CAL] ** rot_i_b = %d, rot_q_b = %d\n",
860 divisor
= ((iq_mag_0_tx
* iq_mag_0_tx
* 2)/1024 - rot_i_b
) * 2;
864 PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> ERROR *******\n"));
865 PHY_DEBUG(("[CAL] ** divisor=0 to calculate EPS and THETA !!\n"));
866 PHY_DEBUG(("[CAL] ******************************************\n"));
870 a_2
= (rot_i_b
* 32768) / divisor
;
871 b_2
= (rot_q_b
* (-32768)) / divisor
;
872 PHY_DEBUG(("[CAL] ***** EPSILON/2 = %d\n", a_2
));
873 PHY_DEBUG(("[CAL] ***** THETA/2 = %d\n", b_2
));
875 phw_data
->iq_rsdl_gain_tx_d2
= a_2
;
876 phw_data
->iq_rsdl_phase_tx_d2
= b_2
;
878 //if ((abs(a_2) < 150) && (abs(b_2) < 100))
879 //if ((abs(a_2) < 200) && (abs(b_2) < 200))
880 if ((abs(a_2
) < a_2_threshold
) && (abs(b_2
) < b_2_threshold
))
884 PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> *************\n"));
885 PHY_DEBUG(("[CAL] ** VERIFY OK # %d !!\n", verify_count
));
886 PHY_DEBUG(("[CAL] ******************************************\n"));
888 if (verify_count
> 2)
890 PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> *********\n"));
891 PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION (EPS,THETA) OK !!\n"));
892 PHY_DEBUG(("[CAL] **************************************\n"));
903 _sin_cos(b_2
, &sin_b
, &cos_b
);
904 _sin_cos(b_2
*2, &sin_2b
, &cos_2b
);
905 PHY_DEBUG(("[CAL] ** sin(b/2)=%d, cos(b/2)=%d\n", sin_b
, cos_b
));
906 PHY_DEBUG(("[CAL] ** sin(b)=%d, cos(b)=%d\n", sin_2b
, cos_2b
));
910 PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> ERROR *******\n"));
911 PHY_DEBUG(("[CAL] ** cos(b)=0 !!\n"));
912 PHY_DEBUG(("[CAL] ******************************************\n"));
916 // 1280 * 32768 = 41943040
917 temp1
= (41943040/cos_2b
)*cos_b
;
919 //temp2 = (41943040/cos_2b)*sin_b*(-1);
920 if (phw_data
->revision
== 0x2002) // 1st-cut
922 temp2
= (41943040/cos_2b
)*sin_b
*(-1);
926 temp2
= (41943040*4/cos_2b
)*sin_b
*(-1);
929 tx_cal_flt_b
[0] = _floor(temp1
/(32768+a_2
));
930 tx_cal_flt_b
[1] = _floor(temp2
/(32768+a_2
));
931 tx_cal_flt_b
[2] = _floor(temp2
/(32768-a_2
));
932 tx_cal_flt_b
[3] = _floor(temp1
/(32768-a_2
));
933 PHY_DEBUG(("[CAL] ** tx_cal_flt_b[0] = %d\n", tx_cal_flt_b
[0]));
934 PHY_DEBUG(("[CAL] tx_cal_flt_b[1] = %d\n", tx_cal_flt_b
[1]));
935 PHY_DEBUG(("[CAL] tx_cal_flt_b[2] = %d\n", tx_cal_flt_b
[2]));
936 PHY_DEBUG(("[CAL] tx_cal_flt_b[3] = %d\n", tx_cal_flt_b
[3]));
938 tx_cal
[2] = tx_cal_flt_b
[2];
939 tx_cal
[2] = tx_cal
[2] +3;
940 tx_cal
[1] = tx_cal
[2];
941 tx_cal
[3] = tx_cal_flt_b
[3] - 128;
942 tx_cal
[0] = -tx_cal
[3]+1;
944 PHY_DEBUG(("[CAL] tx_cal[0] = %d\n", tx_cal
[0]));
945 PHY_DEBUG(("[CAL] tx_cal[1] = %d\n", tx_cal
[1]));
946 PHY_DEBUG(("[CAL] tx_cal[2] = %d\n", tx_cal
[2]));
947 PHY_DEBUG(("[CAL] tx_cal[3] = %d\n", tx_cal
[3]));
949 //if ((tx_cal[0] == 0) && (tx_cal[1] == 0) &&
950 // (tx_cal[2] == 0) && (tx_cal[3] == 0))
952 // PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> *************\n"));
953 // PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION COMPLETE !!\n"));
954 // PHY_DEBUG(("[CAL] ******************************************\n"));
959 if (phw_data
->revision
== 0x2002) // 1st-cut
961 hw_get_dxx_reg(phw_data
, 0x54, &val
);
962 PHY_DEBUG(("[CAL] ** 0x54 = 0x%08X\n", val
));
963 tx_cal_reg
[0] = _s4_to_s32((val
& 0xF0000000) >> 28);
964 tx_cal_reg
[1] = _s4_to_s32((val
& 0x0F000000) >> 24);
965 tx_cal_reg
[2] = _s4_to_s32((val
& 0x00F00000) >> 20);
966 tx_cal_reg
[3] = _s4_to_s32((val
& 0x000F0000) >> 16);
970 hw_get_dxx_reg(phw_data
, 0x3C, &val
);
971 PHY_DEBUG(("[CAL] ** 0x3C = 0x%08X\n", val
));
972 tx_cal_reg
[0] = _s5_to_s32((val
& 0xF8000000) >> 27);
973 tx_cal_reg
[1] = _s6_to_s32((val
& 0x07E00000) >> 21);
974 tx_cal_reg
[2] = _s6_to_s32((val
& 0x001F8000) >> 15);
975 tx_cal_reg
[3] = _s5_to_s32((val
& 0x00007C00) >> 10);
979 PHY_DEBUG(("[CAL] ** tx_cal_reg[0] = %d\n", tx_cal_reg
[0]));
980 PHY_DEBUG(("[CAL] tx_cal_reg[1] = %d\n", tx_cal_reg
[1]));
981 PHY_DEBUG(("[CAL] tx_cal_reg[2] = %d\n", tx_cal_reg
[2]));
982 PHY_DEBUG(("[CAL] tx_cal_reg[3] = %d\n", tx_cal_reg
[3]));
984 if (phw_data
->revision
== 0x2002) // 1st-cut
986 if (((tx_cal_reg
[0]==7) || (tx_cal_reg
[0]==(-8))) &&
987 ((tx_cal_reg
[3]==7) || (tx_cal_reg
[3]==(-8))))
989 PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> *********\n"));
990 PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION SATUATION !!\n"));
991 PHY_DEBUG(("[CAL] **************************************\n"));
997 if (((tx_cal_reg
[0]==31) || (tx_cal_reg
[0]==(-32))) &&
998 ((tx_cal_reg
[3]==31) || (tx_cal_reg
[3]==(-32))))
1000 PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> *********\n"));
1001 PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION SATUATION !!\n"));
1002 PHY_DEBUG(("[CAL] **************************************\n"));
1007 tx_cal
[0] = tx_cal
[0] + tx_cal_reg
[0];
1008 tx_cal
[1] = tx_cal
[1] + tx_cal_reg
[1];
1009 tx_cal
[2] = tx_cal
[2] + tx_cal_reg
[2];
1010 tx_cal
[3] = tx_cal
[3] + tx_cal_reg
[3];
1011 PHY_DEBUG(("[CAL] ** apply tx_cal[0] = %d\n", tx_cal
[0]));
1012 PHY_DEBUG(("[CAL] apply tx_cal[1] = %d\n", tx_cal
[1]));
1013 PHY_DEBUG(("[CAL] apply tx_cal[2] = %d\n", tx_cal
[2]));
1014 PHY_DEBUG(("[CAL] apply tx_cal[3] = %d\n", tx_cal
[3]));
1016 if (phw_data
->revision
== 0x2002) // 1st-cut
1019 val
|= ((_s32_to_s4(tx_cal
[0]) << 28)|
1020 (_s32_to_s4(tx_cal
[1]) << 24)|
1021 (_s32_to_s4(tx_cal
[2]) << 20)|
1022 (_s32_to_s4(tx_cal
[3]) << 16));
1023 hw_set_dxx_reg(phw_data
, 0x54, val
);
1024 PHY_DEBUG(("[CAL] ** CALIB_DATA = 0x%08X\n", val
));
1030 val
|= ((_s32_to_s5(tx_cal
[0]) << 27)|
1031 (_s32_to_s6(tx_cal
[1]) << 21)|
1032 (_s32_to_s6(tx_cal
[2]) << 15)|
1033 (_s32_to_s5(tx_cal
[3]) << 10));
1034 hw_set_dxx_reg(phw_data
, 0x3C, val
);
1035 PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION = 0x%08X\n", val
));
1039 // i. Set "calib_start" to 0x0
1040 reg_mode_ctrl
&= ~MASK_CALIB_START
;
1041 hw_set_dxx_reg(phw_data
, REG_MODE_CTRL
, reg_mode_ctrl
);
1042 PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl
));
1050 void _tx_iq_calibration_winbond(hw_data_t
*phw_data
)
1061 PHY_DEBUG(("[CAL] -> [4]_tx_iq_calibration()\n"));
1063 //0x01 0xEE3FC2 ; 3B8FF ; Calibration (6a). enable TX IQ calibration loop circuits
1064 phy_set_rf_data(phw_data
, 1, (1<<24)|0xEE3FC2);
1065 //0x0B 0x1905D6 ; 06417 ; Calibration (6b). enable TX I/Q cal loop squaring circuit
1066 phy_set_rf_data(phw_data
, 11, (11<<24)|0x19BDD6); // 20060612.1.a 0x1905D6);
1067 //0x05 0x24C60A ; 09318 ; Calibration (6c). setting TX-VGA gain: TXGCH=2 & GPK=110 --> to be optimized
1068 phy_set_rf_data(phw_data
, 5, (5<<24)|0x24C60A); //0x24C60A (high temperature)
1069 //0x06 0x06880C ; 01A20 ; Calibration (6d). RXGCH=00; RXGCL=100 000 (RXVGA=32) --> to be optimized
1070 phy_set_rf_data(phw_data
, 6, (6<<24)|0x34880C); // 20060612.1.a 0x06890C);
1071 //0x00 0xFDF1C0 ; 3F7C7 ; Calibration (6e). turn on IQ imbalance/Test mode
1072 phy_set_rf_data(phw_data
, 0, (0<<24)|0xFDF1C0);
1073 //; [BB-chip]: Calibration (6f).Send test pattern
1074 //; [BB-chip]: Calibration (6g). Search RXGCL optimal value
1075 //; [BB-chip]: Calibration (6h). Caculate TX-path IQ imbalance and setting TX path IQ compensation table
1076 //phy_set_rf_data(phw_data, 3, (3<<24)|0x025586);
1078 OS_SLEEP(30000); // 20060612.1.a 30ms delay. Add the follow 2 lines
1079 //To adjust TXVGA to fit iq_mag_0 range from 1250 ~ 1750
1080 adjust_TXVGA_for_iq_mag( phw_data
);
1083 hw_get_dxx_reg(phw_data
, REG_AGC_CTRL3
, ®_agc_ctrl3
);
1084 reg_agc_ctrl3
&= ~BIT(2);
1085 reg_agc_ctrl3
|= (MASK_LNA_FIX_GAIN
|MASK_AGC_FIX
);
1086 hw_set_dxx_reg(phw_data
, REG_AGC_CTRL3
, reg_agc_ctrl3
);
1088 hw_get_dxx_reg(phw_data
, REG_AGC_CTRL5
, &val
);
1089 val
|= MASK_AGC_FIX_GAIN
;
1090 hw_set_dxx_reg(phw_data
, REG_AGC_CTRL5
, val
);
1092 result
= _tx_iq_calibration_loop_winbond(phw_data
, 150, 100);
1096 if (phw_data
->revision
== 0x2002) // 1st-cut
1098 hw_get_dxx_reg(phw_data
, 0x54, &val
);
1100 hw_set_dxx_reg(phw_data
, 0x54, val
);
1104 hw_get_dxx_reg(phw_data
, 0x3C, &val
);
1106 hw_set_dxx_reg(phw_data
, 0x3C, val
);
1109 result
= _tx_iq_calibration_loop_winbond(phw_data
, 300, 200);
1113 if (phw_data
->revision
== 0x2002) // 1st-cut
1115 hw_get_dxx_reg(phw_data
, 0x54, &val
);
1117 hw_set_dxx_reg(phw_data
, 0x54, val
);
1121 hw_get_dxx_reg(phw_data
, 0x3C, &val
);
1123 hw_set_dxx_reg(phw_data
, 0x3C, val
);
1126 result
= _tx_iq_calibration_loop_winbond(phw_data
, 500, 400);
1129 if (phw_data
->revision
== 0x2002) // 1st-cut
1131 hw_get_dxx_reg(phw_data
, 0x54, &val
);
1133 hw_set_dxx_reg(phw_data
, 0x54, val
);
1137 hw_get_dxx_reg(phw_data
, 0x3C, &val
);
1139 hw_set_dxx_reg(phw_data
, 0x3C, val
);
1143 result
= _tx_iq_calibration_loop_winbond(phw_data
, 700, 500);
1147 PHY_DEBUG(("[CAL] ** <_tx_iq_calibration> **************\n"));
1148 PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION FAILURE !!\n"));
1149 PHY_DEBUG(("[CAL] **************************************\n"));
1151 if (phw_data
->revision
== 0x2002) // 1st-cut
1153 hw_get_dxx_reg(phw_data
, 0x54, &val
);
1155 hw_set_dxx_reg(phw_data
, 0x54, val
);
1159 hw_get_dxx_reg(phw_data
, 0x3C, &val
);
1161 hw_set_dxx_reg(phw_data
, 0x3C, val
);
1168 // i. Set "calib_start" to 0x0
1169 hw_get_dxx_reg(phw_data
, REG_MODE_CTRL
, ®_mode_ctrl
);
1170 reg_mode_ctrl
&= ~MASK_CALIB_START
;
1171 hw_set_dxx_reg(phw_data
, REG_MODE_CTRL
, reg_mode_ctrl
);
1172 PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl
));
1175 //hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, &val);
1176 reg_agc_ctrl3
|= BIT(2);
1177 reg_agc_ctrl3
&= ~(MASK_LNA_FIX_GAIN
|MASK_AGC_FIX
);
1178 hw_set_dxx_reg(phw_data
, REG_AGC_CTRL3
, reg_agc_ctrl3
);
1181 if (phw_data
->revision
== 0x2002) // 1st-cut
1183 hw_get_dxx_reg(phw_data
, 0x54, &val
);
1184 PHY_DEBUG(("[CAL] ** 0x54 = 0x%08X\n", val
));
1185 tx_cal_reg
[0] = _s4_to_s32((val
& 0xF0000000) >> 28);
1186 tx_cal_reg
[1] = _s4_to_s32((val
& 0x0F000000) >> 24);
1187 tx_cal_reg
[2] = _s4_to_s32((val
& 0x00F00000) >> 20);
1188 tx_cal_reg
[3] = _s4_to_s32((val
& 0x000F0000) >> 16);
1192 hw_get_dxx_reg(phw_data
, 0x3C, &val
);
1193 PHY_DEBUG(("[CAL] ** 0x3C = 0x%08X\n", val
));
1194 tx_cal_reg
[0] = _s5_to_s32((val
& 0xF8000000) >> 27);
1195 tx_cal_reg
[1] = _s6_to_s32((val
& 0x07E00000) >> 21);
1196 tx_cal_reg
[2] = _s6_to_s32((val
& 0x001F8000) >> 15);
1197 tx_cal_reg
[3] = _s5_to_s32((val
& 0x00007C00) >> 10);
1201 PHY_DEBUG(("[CAL] ** tx_cal_reg[0] = %d\n", tx_cal_reg
[0]));
1202 PHY_DEBUG(("[CAL] tx_cal_reg[1] = %d\n", tx_cal_reg
[1]));
1203 PHY_DEBUG(("[CAL] tx_cal_reg[2] = %d\n", tx_cal_reg
[2]));
1204 PHY_DEBUG(("[CAL] tx_cal_reg[3] = %d\n", tx_cal_reg
[3]));
1209 // RF Control Override
1212 /////////////////////////////////////////////////////////////////////////////////////////
1213 u8
_rx_iq_calibration_loop_winbond(hw_data_t
*phw_data
, u16 factor
, u32 frequency
)
1224 s32 rx_cal_flt_b
[4];
1238 s32 iqcal_tone_i_avg
,iqcal_tone_q_avg
;
1239 s32 iqcal_image_i_avg
,iqcal_image_q_avg
;
1242 PHY_DEBUG(("[CAL] -> [5]_rx_iq_calibration_loop()\n"));
1243 PHY_DEBUG(("[CAL] ** factor = %d\n", factor
));
1246 // RF Control Override
1247 hw_get_cxx_reg(phw_data
, 0x80, &val
);
1249 hw_set_cxx_reg(phw_data
, 0x80, val
);
1252 hw_get_cxx_reg(phw_data
, 0xE4, &val
);
1254 hw_set_cxx_reg(phw_data
, 0xE4, val
);
1255 PHY_DEBUG(("[CAL] ** RF_CTRL(0xE4) = 0x%08X", val
));
1257 hw_set_dxx_reg(phw_data
, 0x58, 0x44444444); // IQ_Alpha
1261 hw_get_dxx_reg(phw_data
, REG_MODE_CTRL
, ®_mode_ctrl
);
1262 PHY_DEBUG(("[CAL] MODE_CTRL (read) = 0x%08X\n", reg_mode_ctrl
));
1266 //for (loop = 0; loop < 1; loop++)
1267 //for (loop = 0; loop < LOOP_TIMES; loop++)
1271 PHY_DEBUG(("[CAL] [%d.] <_rx_iq_calibration_loop>\n", (LOOP_TIMES
-loop
+1)));
1274 iqcal_image_i_avg
=0;
1275 iqcal_image_q_avg
=0;
1278 for(capture_time
=0; capture_time
<10; capture_time
++)
1280 // i. Set "calib_start" to 0x0
1281 reg_mode_ctrl
&= ~MASK_CALIB_START
;
1282 if( !hw_set_dxx_reg(phw_data
, REG_MODE_CTRL
, reg_mode_ctrl
) )//20060718.1 modify
1284 PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl
));
1285 pa_stall_execution(US
);
1287 reg_mode_ctrl
&= ~MASK_IQCAL_MODE
;
1288 reg_mode_ctrl
|= (MASK_CALIB_START
|0x1);
1289 hw_set_dxx_reg(phw_data
, REG_MODE_CTRL
, reg_mode_ctrl
);
1290 PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl
));
1291 pa_stall_execution(US
); //Should be read out after 450us
1294 hw_get_dxx_reg(phw_data
, REG_CALIB_READ1
, &val
);
1295 PHY_DEBUG(("[CAL] CALIB_READ1 = 0x%08X\n", val
));
1297 iqcal_tone_i
= _s13_to_s32(val
& 0x00001FFF);
1298 iqcal_tone_q
= _s13_to_s32((val
& 0x03FFE000) >> 13);
1299 PHY_DEBUG(("[CAL] ** iqcal_tone_i = %d, iqcal_tone_q = %d\n",
1300 iqcal_tone_i
, iqcal_tone_q
));
1302 hw_get_dxx_reg(phw_data
, REG_CALIB_READ2
, &val
);
1303 PHY_DEBUG(("[CAL] CALIB_READ2 = 0x%08X\n", val
));
1305 iqcal_image_i
= _s13_to_s32(val
& 0x00001FFF);
1306 iqcal_image_q
= _s13_to_s32((val
& 0x03FFE000) >> 13);
1307 PHY_DEBUG(("[CAL] ** iqcal_image_i = %d, iqcal_image_q = %d\n",
1308 iqcal_image_i
, iqcal_image_q
));
1309 if( capture_time
== 0)
1315 iqcal_image_i_avg
=( iqcal_image_i_avg
*(capture_time
-1) +iqcal_image_i
)/capture_time
;
1316 iqcal_image_q_avg
=( iqcal_image_q_avg
*(capture_time
-1) +iqcal_image_q
)/capture_time
;
1317 iqcal_tone_i_avg
=( iqcal_tone_i_avg
*(capture_time
-1) +iqcal_tone_i
)/capture_time
;
1318 iqcal_tone_q_avg
=( iqcal_tone_q_avg
*(capture_time
-1) +iqcal_tone_q
)/capture_time
;
1323 iqcal_image_i
= iqcal_image_i_avg
;
1324 iqcal_image_q
= iqcal_image_q_avg
;
1325 iqcal_tone_i
= iqcal_tone_i_avg
;
1326 iqcal_tone_q
= iqcal_tone_q_avg
;
1329 rot_tone_i_b
= (iqcal_tone_i
* iqcal_tone_i
+
1330 iqcal_tone_q
* iqcal_tone_q
) / 1024;
1331 rot_tone_q_b
= (iqcal_tone_i
* iqcal_tone_q
* (-1) +
1332 iqcal_tone_q
* iqcal_tone_i
) / 1024;
1333 rot_image_i_b
= (iqcal_image_i
* iqcal_tone_i
-
1334 iqcal_image_q
* iqcal_tone_q
) / 1024;
1335 rot_image_q_b
= (iqcal_image_i
* iqcal_tone_q
+
1336 iqcal_image_q
* iqcal_tone_i
) / 1024;
1338 PHY_DEBUG(("[CAL] ** rot_tone_i_b = %d\n", rot_tone_i_b
));
1339 PHY_DEBUG(("[CAL] ** rot_tone_q_b = %d\n", rot_tone_q_b
));
1340 PHY_DEBUG(("[CAL] ** rot_image_i_b = %d\n", rot_image_i_b
));
1341 PHY_DEBUG(("[CAL] ** rot_image_q_b = %d\n", rot_image_q_b
));
1344 if (rot_tone_i_b
== 0)
1346 PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> ERROR *******\n"));
1347 PHY_DEBUG(("[CAL] ** rot_tone_i_b=0 to calculate EPS and THETA !!\n"));
1348 PHY_DEBUG(("[CAL] ******************************************\n"));
1352 a_2
= (rot_image_i_b
* 32768) / rot_tone_i_b
-
1353 phw_data
->iq_rsdl_gain_tx_d2
;
1354 b_2
= (rot_image_q_b
* 32768) / rot_tone_i_b
-
1355 phw_data
->iq_rsdl_phase_tx_d2
;
1357 PHY_DEBUG(("[CAL] ** iq_rsdl_gain_tx_d2 = %d\n", phw_data
->iq_rsdl_gain_tx_d2
));
1358 PHY_DEBUG(("[CAL] ** iq_rsdl_phase_tx_d2= %d\n", phw_data
->iq_rsdl_phase_tx_d2
));
1359 PHY_DEBUG(("[CAL] ***** EPSILON/2 = %d\n", a_2
));
1360 PHY_DEBUG(("[CAL] ***** THETA/2 = %d\n", b_2
));
1362 _sin_cos(b_2
, &sin_b
, &cos_b
);
1363 _sin_cos(b_2
*2, &sin_2b
, &cos_2b
);
1364 PHY_DEBUG(("[CAL] ** sin(b/2)=%d, cos(b/2)=%d\n", sin_b
, cos_b
));
1365 PHY_DEBUG(("[CAL] ** sin(b)=%d, cos(b)=%d\n", sin_2b
, cos_2b
));
1369 PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> ERROR *******\n"));
1370 PHY_DEBUG(("[CAL] ** cos(b)=0 !!\n"));
1371 PHY_DEBUG(("[CAL] ******************************************\n"));
1375 // 1280 * 32768 = 41943040
1376 temp1
= (41943040/cos_2b
)*cos_b
;
1378 //temp2 = (41943040/cos_2b)*sin_b*(-1);
1379 if (phw_data
->revision
== 0x2002) // 1st-cut
1381 temp2
= (41943040/cos_2b
)*sin_b
*(-1);
1385 temp2
= (41943040*4/cos_2b
)*sin_b
*(-1);
1388 rx_cal_flt_b
[0] = _floor(temp1
/(32768+a_2
));
1389 rx_cal_flt_b
[1] = _floor(temp2
/(32768-a_2
));
1390 rx_cal_flt_b
[2] = _floor(temp2
/(32768+a_2
));
1391 rx_cal_flt_b
[3] = _floor(temp1
/(32768-a_2
));
1393 PHY_DEBUG(("[CAL] ** rx_cal_flt_b[0] = %d\n", rx_cal_flt_b
[0]));
1394 PHY_DEBUG(("[CAL] rx_cal_flt_b[1] = %d\n", rx_cal_flt_b
[1]));
1395 PHY_DEBUG(("[CAL] rx_cal_flt_b[2] = %d\n", rx_cal_flt_b
[2]));
1396 PHY_DEBUG(("[CAL] rx_cal_flt_b[3] = %d\n", rx_cal_flt_b
[3]));
1398 rx_cal
[0] = rx_cal_flt_b
[0] - 128;
1399 rx_cal
[1] = rx_cal_flt_b
[1];
1400 rx_cal
[2] = rx_cal_flt_b
[2];
1401 rx_cal
[3] = rx_cal_flt_b
[3] - 128;
1402 PHY_DEBUG(("[CAL] ** rx_cal[0] = %d\n", rx_cal
[0]));
1403 PHY_DEBUG(("[CAL] rx_cal[1] = %d\n", rx_cal
[1]));
1404 PHY_DEBUG(("[CAL] rx_cal[2] = %d\n", rx_cal
[2]));
1405 PHY_DEBUG(("[CAL] rx_cal[3] = %d\n", rx_cal
[3]));
1408 pwr_tone
= (iqcal_tone_i
*iqcal_tone_i
+ iqcal_tone_q
*iqcal_tone_q
);
1409 pwr_image
= (iqcal_image_i
*iqcal_image_i
+ iqcal_image_q
*iqcal_image_q
)*factor
;
1411 PHY_DEBUG(("[CAL] ** pwr_tone = %d\n", pwr_tone
));
1412 PHY_DEBUG(("[CAL] ** pwr_image = %d\n", pwr_image
));
1414 if (pwr_tone
> pwr_image
)
1418 PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> *************\n"));
1419 PHY_DEBUG(("[CAL] ** VERIFY OK # %d !!\n", verify_count
));
1420 PHY_DEBUG(("[CAL] ******************************************\n"));
1422 if (verify_count
> 2)
1424 PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> *********\n"));
1425 PHY_DEBUG(("[CAL] ** RX_IQ_CALIBRATION OK !!\n"));
1426 PHY_DEBUG(("[CAL] **************************************\n"));
1433 hw_get_dxx_reg(phw_data
, 0x54, &val
);
1434 PHY_DEBUG(("[CAL] ** 0x54 = 0x%08X\n", val
));
1436 if (phw_data
->revision
== 0x2002) // 1st-cut
1438 rx_cal_reg
[0] = _s4_to_s32((val
& 0x0000F000) >> 12);
1439 rx_cal_reg
[1] = _s4_to_s32((val
& 0x00000F00) >> 8);
1440 rx_cal_reg
[2] = _s4_to_s32((val
& 0x000000F0) >> 4);
1441 rx_cal_reg
[3] = _s4_to_s32((val
& 0x0000000F));
1445 rx_cal_reg
[0] = _s5_to_s32((val
& 0xF8000000) >> 27);
1446 rx_cal_reg
[1] = _s6_to_s32((val
& 0x07E00000) >> 21);
1447 rx_cal_reg
[2] = _s6_to_s32((val
& 0x001F8000) >> 15);
1448 rx_cal_reg
[3] = _s5_to_s32((val
& 0x00007C00) >> 10);
1451 PHY_DEBUG(("[CAL] ** rx_cal_reg[0] = %d\n", rx_cal_reg
[0]));
1452 PHY_DEBUG(("[CAL] rx_cal_reg[1] = %d\n", rx_cal_reg
[1]));
1453 PHY_DEBUG(("[CAL] rx_cal_reg[2] = %d\n", rx_cal_reg
[2]));
1454 PHY_DEBUG(("[CAL] rx_cal_reg[3] = %d\n", rx_cal_reg
[3]));
1456 if (phw_data
->revision
== 0x2002) // 1st-cut
1458 if (((rx_cal_reg
[0]==7) || (rx_cal_reg
[0]==(-8))) &&
1459 ((rx_cal_reg
[3]==7) || (rx_cal_reg
[3]==(-8))))
1461 PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> *********\n"));
1462 PHY_DEBUG(("[CAL] ** RX_IQ_CALIBRATION SATUATION !!\n"));
1463 PHY_DEBUG(("[CAL] **************************************\n"));
1469 if (((rx_cal_reg
[0]==31) || (rx_cal_reg
[0]==(-32))) &&
1470 ((rx_cal_reg
[3]==31) || (rx_cal_reg
[3]==(-32))))
1472 PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> *********\n"));
1473 PHY_DEBUG(("[CAL] ** RX_IQ_CALIBRATION SATUATION !!\n"));
1474 PHY_DEBUG(("[CAL] **************************************\n"));
1479 rx_cal
[0] = rx_cal
[0] + rx_cal_reg
[0];
1480 rx_cal
[1] = rx_cal
[1] + rx_cal_reg
[1];
1481 rx_cal
[2] = rx_cal
[2] + rx_cal_reg
[2];
1482 rx_cal
[3] = rx_cal
[3] + rx_cal_reg
[3];
1483 PHY_DEBUG(("[CAL] ** apply rx_cal[0] = %d\n", rx_cal
[0]));
1484 PHY_DEBUG(("[CAL] apply rx_cal[1] = %d\n", rx_cal
[1]));
1485 PHY_DEBUG(("[CAL] apply rx_cal[2] = %d\n", rx_cal
[2]));
1486 PHY_DEBUG(("[CAL] apply rx_cal[3] = %d\n", rx_cal
[3]));
1488 hw_get_dxx_reg(phw_data
, 0x54, &val
);
1489 if (phw_data
->revision
== 0x2002) // 1st-cut
1492 val
|= ((_s32_to_s4(rx_cal
[0]) << 12)|
1493 (_s32_to_s4(rx_cal
[1]) << 8)|
1494 (_s32_to_s4(rx_cal
[2]) << 4)|
1495 (_s32_to_s4(rx_cal
[3])));
1496 hw_set_dxx_reg(phw_data
, 0x54, val
);
1501 val
|= ((_s32_to_s5(rx_cal
[0]) << 27)|
1502 (_s32_to_s6(rx_cal
[1]) << 21)|
1503 (_s32_to_s6(rx_cal
[2]) << 15)|
1504 (_s32_to_s5(rx_cal
[3]) << 10));
1505 hw_set_dxx_reg(phw_data
, 0x54, val
);
1510 PHY_DEBUG(("[CAL] ** CALIB_DATA = 0x%08X\n", val
));
1518 //////////////////////////////////////////////////////////
1520 //////////////////////////////////////////////////////////////////////////
1521 void _rx_iq_calibration_winbond(hw_data_t
*phw_data
, u32 frequency
)
1523 // figo 20050523 marked thsi flag for can't compile for relesase
1531 PHY_DEBUG(("[CAL] -> [5]_rx_iq_calibration()\n"));
1532 // a. Set RFIC to "RX calibration mode"
1533 //; ----- Calibration (7). RX path IQ imbalance calibration loop
1534 // 0x01 0xFFBFC2 ; 3FEFF ; Calibration (7a). enable RX IQ calibration loop circuits
1535 phy_set_rf_data(phw_data
, 1, (1<<24)|0xEFBFC2);
1536 // 0x0B 0x1A01D6 ; 06817 ; Calibration (7b). enable RX I/Q cal loop SW1 circuit
1537 phy_set_rf_data(phw_data
, 11, (11<<24)|0x1A05D6);
1538 //0x05 0x24848A ; 09212 ; Calibration (7c). setting TX-VGA gain (TXGCH) to 2 --> to be optimized
1539 phy_set_rf_data(phw_data
, 5, (5<<24)| phw_data
->txvga_setting_for_cal
);
1540 //0x06 0x06840C ; 01A10 ; Calibration (7d). RXGCH=00; RXGCL=010 000 (RXVGA) --> to be optimized
1541 phy_set_rf_data(phw_data
, 6, (6<<24)|0x06834C);
1542 //0x00 0xFFF1C0 ; 3F7C7 ; Calibration (7e). turn on IQ imbalance/Test mode
1543 phy_set_rf_data(phw_data
, 0, (0<<24)|0xFFF1C0);
1545 // ; [BB-chip]: Calibration (7f). Send test pattern
1546 // ; [BB-chip]: Calibration (7g). Search RXGCL optimal value
1547 // ; [BB-chip]: Calibration (7h). Caculate RX-path IQ imbalance and setting RX path IQ compensation table
1549 result
= _rx_iq_calibration_loop_winbond(phw_data
, 12589, frequency
);
1553 _reset_rx_cal(phw_data
);
1554 result
= _rx_iq_calibration_loop_winbond(phw_data
, 7943, frequency
);
1558 _reset_rx_cal(phw_data
);
1559 result
= _rx_iq_calibration_loop_winbond(phw_data
, 5011, frequency
);
1563 PHY_DEBUG(("[CAL] ** <_rx_iq_calibration> **************\n"));
1564 PHY_DEBUG(("[CAL] ** RX_IQ_CALIBRATION FAILURE !!\n"));
1565 PHY_DEBUG(("[CAL] **************************************\n"));
1566 _reset_rx_cal(phw_data
);
1572 hw_get_dxx_reg(phw_data
, 0x54, &val
);
1573 PHY_DEBUG(("[CAL] ** 0x54 = 0x%08X\n", val
));
1575 if (phw_data
->revision
== 0x2002) // 1st-cut
1577 rx_cal_reg
[0] = _s4_to_s32((val
& 0x0000F000) >> 12);
1578 rx_cal_reg
[1] = _s4_to_s32((val
& 0x00000F00) >> 8);
1579 rx_cal_reg
[2] = _s4_to_s32((val
& 0x000000F0) >> 4);
1580 rx_cal_reg
[3] = _s4_to_s32((val
& 0x0000000F));
1584 rx_cal_reg
[0] = _s5_to_s32((val
& 0xF8000000) >> 27);
1585 rx_cal_reg
[1] = _s6_to_s32((val
& 0x07E00000) >> 21);
1586 rx_cal_reg
[2] = _s6_to_s32((val
& 0x001F8000) >> 15);
1587 rx_cal_reg
[3] = _s5_to_s32((val
& 0x00007C00) >> 10);
1590 PHY_DEBUG(("[CAL] ** rx_cal_reg[0] = %d\n", rx_cal_reg
[0]));
1591 PHY_DEBUG(("[CAL] rx_cal_reg[1] = %d\n", rx_cal_reg
[1]));
1592 PHY_DEBUG(("[CAL] rx_cal_reg[2] = %d\n", rx_cal_reg
[2]));
1593 PHY_DEBUG(("[CAL] rx_cal_reg[3] = %d\n", rx_cal_reg
[3]));
1598 ////////////////////////////////////////////////////////////////////////
1599 void phy_calibration_winbond(hw_data_t
*phw_data
, u32 frequency
)
1604 PHY_DEBUG(("[CAL] -> phy_calibration_winbond()\n"));
1606 // 20040701 1.1.25.1000 kevin
1607 hw_get_cxx_reg(phw_data
, 0x80, &mac_ctrl
);
1608 hw_get_cxx_reg(phw_data
, 0xE4, &rf_ctrl
);
1609 hw_get_dxx_reg(phw_data
, 0x58, &iq_alpha
);
1613 _rxadc_dc_offset_cancellation_winbond(phw_data
, frequency
);
1614 //_txidac_dc_offset_cancellation_winbond(phw_data);
1615 //_txqdac_dc_offset_cacellation_winbond(phw_data);
1617 _tx_iq_calibration_winbond(phw_data
);
1618 _rx_iq_calibration_winbond(phw_data
, frequency
);
1620 //------------------------------------------------------------------------
1621 hw_get_dxx_reg(phw_data
, REG_MODE_CTRL
, ®_mode_ctrl
);
1622 reg_mode_ctrl
&= ~(MASK_IQCAL_TONE_SEL
|MASK_IQCAL_MODE
|MASK_CALIB_START
); // set when finish
1623 hw_set_dxx_reg(phw_data
, REG_MODE_CTRL
, reg_mode_ctrl
);
1624 PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl
));
1626 // i. Set RFIC to "Normal mode"
1627 hw_set_cxx_reg(phw_data
, 0x80, mac_ctrl
);
1628 hw_set_cxx_reg(phw_data
, 0xE4, rf_ctrl
);
1629 hw_set_dxx_reg(phw_data
, 0x58, iq_alpha
);
1632 //------------------------------------------------------------------------
1633 phy_init_rf(phw_data
);
1637 //===========================
1638 void phy_set_rf_data( phw_data_t pHwData
, u32 index
, u32 value
)
1642 switch( pHwData
->phy_type
)
1645 case RF_MAXIM_V1
: // 11g Winbond 2nd BB(with Phy board (v1) + Maxim 331)
1646 ltmp
= (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( value
, 18 );
1650 ltmp
= (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( value
, 18 );
1654 ltmp
= (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( value
, 18 );
1658 ltmp
= (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( value
, 18 );
1661 case RF_AIROHA_2230
:
1662 case RF_AIROHA_2230S
: // 20060420 Add this
1663 ltmp
= (1 << 31) | (0 << 30) | (20 << 24) | BitReverse( value
, 20 );
1666 case RF_AIROHA_7230
:
1667 ltmp
= (1 << 31) | (0 << 30) | (24 << 24) | (value
&0xffffff);
1671 case RF_WB_242_1
: // 20060619.5 Add
1672 ltmp
= (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( value
, 24 );
1676 Wb35Reg_WriteSync( pHwData
, 0x0864, ltmp
);
1679 // 20060717 modify as Bruce's mail
1680 unsigned char adjust_TXVGA_for_iq_mag(hw_data_t
*phw_data
)
1694 for( init_txvga
=0; init_txvga
<10; init_txvga
++)
1696 current_txvga
= ( 0x24C40A|(init_txvga
<<6) );
1697 phy_set_rf_data(phw_data
, 5, ((5<<24)|current_txvga
) );
1698 phw_data
->txvga_setting_for_cal
= current_txvga
;
1700 //pa_stall_execution(30000);//Sleep(30);
1701 OS_SLEEP(30000); // 20060612.1.a
1703 if( !hw_get_dxx_reg(phw_data
, REG_MODE_CTRL
, ®_mode_ctrl
) ) // 20060718.1 modify
1706 PHY_DEBUG(("[CAL] MODE_CTRL (read) = 0x%08X\n", reg_mode_ctrl
));
1708 // a. Set iqcal_mode[1:0] to 0x2 and set "calib_start" to 0x1 to
1709 // enable "IQ alibration Mode II"
1710 reg_mode_ctrl
&= ~(MASK_IQCAL_TONE_SEL
|MASK_IQCAL_MODE
);
1711 reg_mode_ctrl
&= ~MASK_IQCAL_MODE
;
1712 reg_mode_ctrl
|= (MASK_CALIB_START
|0x02);
1713 reg_mode_ctrl
|= (MASK_CALIB_START
|0x02|2<<2);
1714 hw_set_dxx_reg(phw_data
, REG_MODE_CTRL
, reg_mode_ctrl
);
1715 PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl
));
1717 //pa_stall_execution(US);
1718 OS_SLEEP(1); // 20060612.1.a
1720 //pa_stall_execution(300);//Sleep(30);
1721 OS_SLEEP(300); // 20060612.1.a
1724 hw_get_dxx_reg(phw_data
, REG_CALIB_READ1
, &val
);
1726 PHY_DEBUG(("[CAL] CALIB_READ1 = 0x%08X\n", val
));
1727 //pa_stall_execution(US);
1728 //pa_stall_execution(300);//Sleep(30);
1729 OS_SLEEP(300); // 20060612.1.a
1731 iqcal_tone_i0
= _s13_to_s32(val
& 0x00001FFF);
1732 iqcal_tone_q0
= _s13_to_s32((val
& 0x03FFE000) >> 13);
1733 PHY_DEBUG(("[CAL] ** iqcal_tone_i0=%d, iqcal_tone_q0=%d\n",
1734 iqcal_tone_i0
, iqcal_tone_q0
));
1736 sqsum
= iqcal_tone_i0
*iqcal_tone_i0
+ iqcal_tone_q0
*iqcal_tone_q0
;
1737 iq_mag_0_tx
= (s32
) _sqrt(sqsum
);
1738 PHY_DEBUG(("[CAL] ** auto_adjust_txvga_for_iq_mag_0_tx=%d\n", iq_mag_0_tx
));
1740 if( iq_mag_0_tx
>=700 && iq_mag_0_tx
<=1750 )
1742 else if(iq_mag_0_tx
> 1750)
1752 if( iq_mag_0_tx
>=700 && iq_mag_0_tx
<=1750 )