1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
//! Calibration table SRAM packing/unpacking.
//!
//! The RFC hardware reads per-channel VCO and per-power-level TXDC
//! calibration data from SRAM tables addressed by `CAL_ADDR_REG1/2/3`.
//! The bit layout of these table entries is vendor-specific.
//!
//! # Table formats
//!
//! ## VCO RX table (addressed by `CAL_ADDR_REG1`)
//!
//! Each 32-bit word packs two 16-bit halfwords. For BLE RX, the low half
//! is the 1M PHY entry and the high half is the 2M PHY entry. For BT RX,
//! each half is a separate channel (ch0=low, ch1=high).
//!
//! Halfword format: `capcode[7:0] | idac[15:8]`
//!
//! ## VCO TX table (addressed by `CAL_ADDR_REG2`)
//!
//! Each 32-bit word: `capcode[7:0] | idac[14:8] | kcal[31:16]`
//!
//! ## BT TX table (EDR, also addressed by `CAL_ADDR_REG2`)
//!
//! Each 32-bit word matches [`EDR_CAL_REG1`](super::regs::edr_cal_reg1)
//! register layout, loaded by the `RD_FULCAL` command during `BT_TXON`.
//! See [`pack_edr_cal`] for the full bit layout including scattered DPSK
//! gain bits.
//!
//! ## TXDC table (addressed by `CAL_ADDR_REG3`)
//!
//! Two 32-bit words per power level:
//! - Word 1 matches [`IQ_PWR_REG1`](super::regs::iq_pwr_reg1), loaded by `RD_DCCAL1`.
//! - Word 2 matches [`IQ_PWR_REG2`](super::regs::iq_pwr_reg2), loaded by `RD_DCCAL2`.
// ============================================================================
// VCO calibration table packing
// ============================================================================
/// Pack a VCO RX halfword: `capcode[7:0] | idac[15:8]`.
///
/// Used in both BLE RX and BT RX tables. Two halfwords are combined
/// with [`pack_vco_rx_word`] to form a 32-bit SRAM entry.
pub const
/// Pack two VCO RX halfwords into a 32-bit SRAM word.
///
/// - For BLE RX: `low` = 1M PHY, `high` = 2M PHY.
/// - For BT RX: `low` = even channel, `high` = odd channel.
pub const
/// Pack a VCO TX calibration word: `capcode[7:0] | idac[14:8] | kcal[31:16]`.
///
/// One word per channel (79 channels for BLE TX, 79 for BT TX).
/// The `RD_FULCAL` command during `TXON` loads this into the VCO control
/// registers.
pub const
// ============================================================================
// TXDC calibration table packing
// ============================================================================
/// Packed TXDC calibration entry (two 32-bit words per power level).
/// Pack a TXDC calibration table entry.
///
/// - `coef0`, `coef1`: 14-bit DC calibration coefficients.
/// - `offset_i`, `offset_q`: 11-bit DC offset values.
/// - `tmxbuf_gc`: 4-bit TX mixer buffer gain control (same value in both words).
/// - `edr_pa_bm`: 5-bit EDR PA bias current.
pub const
// ============================================================================
// EDR_CAL_REG1 calibration table packing
// ============================================================================
/// Pack an EDR calibration table word matching the `EDR_CAL_REG1` register layout.
///
/// This format is used in the BT TX calibration table (addressed by
/// `CAL_ADDR_REG2.bt_tx_cal_addr`). The MAC's `RD_FULCAL` command during
/// `BT_TXON` sequences loads this word directly into `EDR_CAL_REG1`.
///
/// # Bit layout
///
/// ```text
/// [7:0] capcode (brf_edr_vco_pdx_lv)
/// [14:8] idac (brf_edr_vco_idac_lv)
/// [15] dpsk_gain scattered bit 0
/// [18:16] oslo_fc (brf_oslo_fc_lv)
/// [19] dpsk_gain scattered bit 1
/// [24:20] oslo_bm (brf_oslo_bm_lv)
/// [27:25] dpsk_gain scattered bits 4:2
/// [31:28] tmxcap (brf_trf_edr_tmxcap_sel_lv)
/// ```
///
/// # DPSK gain scattering
///
/// The 6-bit `dpsk_gain` value is right-shifted by 1 (dropping bit 0),
/// then the remaining 5 bits are scattered into the "holes" between
/// the named register fields:
///
/// - `(dpsk_gain >> 1) & 0x01` → bit 15
/// - `(dpsk_gain >> 1) & 0x02` → bit 19
/// - `(dpsk_gain >> 1) & 0x1C` → bits 27:25
pub const