1 /*!
2 * Copyright (c) 2015, Freescale Semiconductor, Inc.
3 * All rights reserved.
4 *
5 * \file tsm_ll_timing.c
6 * TSM and LL timing register initialization code for MKW40Z4.
7 *
8 * Redistribution and use in source and binary forms, with or without modification,
9 * are permitted provided that the following conditions are met:
10 *
11 * o Redistributions of source code must retain the above copyright notice, this list
12 * of conditions and the following disclaimer.
13 *
14 * o Redistributions in binary form must reproduce the above copyright notice, this
15 * list of conditions and the following disclaimer in the documentation and/or
16 * other materials provided with the distribution.
17 *
18 * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
19 * contributors may be used to endorse or promote products derived from this
20 * software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
26 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
29 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 /*! *********************************************************************************
35 *************************************************************************************
36 * Include
37 *************************************************************************************
38 ********************************************************************************** */
39 #include <stdint.h>
40 #include "tsm_ll_timing.h"
41 #include "fsl_device_registers.h"
42
43 /*! *********************************************************************************
44 *************************************************************************************
45 * Constants
46 *************************************************************************************
47 ********************************************************************************** */
48 #define USE_RAM_TESTING 0
49 #define END_OF_SEQ_END_OF_TX_WU_MASK 0xFF
50 #define END_OF_SEQ_END_OF_TX_WU_SHIFT 0
51
52 #define END_OF_SEQ_END_OF_TX_WD_MASK 0xFF00
53 #define END_OF_SEQ_END_OF_TX_WD_SHIFT 8
54
55 #define END_OF_SEQ_END_OF_RX_WU_MASK 0xFF0000
56 #define END_OF_SEQ_END_OF_RX_WU_SHIFT 16
57
58 #define END_OF_SEQ_END_OF_RX_WD_MASK 0xFF000000
59 #define END_OF_SEQ_END_OF_RX_WD_SHIFT 24
60
61 #define BLE_REG_BASE 0x4005B000
62 #define TX_RX_ON_DELAY ( 0x190 ) /* 32-bit:0x190 address */
63 #define TX_RX_SYNTH_DELAY ( 0x198 ) /* 32-bit:0x198 address */
64
65 #define PLL_REG_EN_INDEX (0)
66 #define PLL_VCO_REG_EN_INDEX (1)
67 #define PLL_QGEN_REG_EN_INDEX (2)
68 #define PLL_TCA_TX_REG_EN_INDEX (3)
69 #define ADC_REG_EN_INDEX (4)
70 #define PLL_REF_CLK_EN_INDEX (5)
71 #define ADC_CLK_EN_INDEX (6)
72 #define PLL_VCO_AUTOTUNE_INDEX (7)
73 #define PLL_CYCLE_SLIP_LD_EN_INDEX (8)
74 #define PLL_VCO_EN_INDEX (9)
75 #define PLL_VCO_BUF_RX_EN_INDEX (10)
76 #define PLL_VCO_BUF_TX_EN_INDEX (11)
77 #define PLL_PA_BUF_EN_INDEX (12)
78 #define PLL_LDV_EN_INDEX (13)
79 #define PLL_RX_LDV_RIPPLE_MUX_EN_INDEX (14)
80 #define PLL_TX_LDV_RIPPLE_MUX_EN_INDEX (15)
81 #define PLL_FILTER_CHARGE_EN_INDEX (16)
82 #define PLL_PHDET_EN_INDEX (17)
83 #define QGEN25_EN_INDEX (18)
84 #define TX_EN_INDEX (19)
85 #define ADC_EN_INDEX (20)
86 #define ADC_I_Q_EN_INDEX (21)
87 #define ADC_DAC_EN_INDEX (22)
88 #define ADC_RST_EN_INDEX (23)
89 #define BBF_EN_INDEX (24)
90 #define TCA_EN_INDEX (25)
91 #define PLL_DIG_EN_INDEX (26)
92 #define TX_DIG_EN_INDEX (27)
93 #define RX_DIG_EN_INDEX (28)
94 #define RX_INIT_INDEX (29)
95 #define SIGMA_DELTA_EN_INDEX (30)
96 #define ZBDEM_RX_EN_INDEX (31)
97 #define DCOC_EN_INDEX (32)
98 #define DCOC_INIT_EN_INDEX (33)
99 #define FREQ_TARG_LD_EN_INDEX (34)
100 #define SAR_ADC_TRIG_EN_INDEX (35)
101 #define TSM_SPARE0_EN_INDEX (36)
102 #define TSM_SPARE1_EN_INDEX (37)
103 #define TSM_SPARE2_EN_INDEX (38)
104 #define TSM_SPARE03_EN_INDEX (39)
105 #define GPIO0_TRIG_EN_INDEX (40)
106 #define GPIO1_TRIG_EN_INDEX (41)
107 #define GPIO2_TRIG_EN_INDEX (42)
108 #define GPIO3_TRIG_EN_INDEX (43)
109
110 /*! *********************************************************************************
111 *************************************************************************************
112 * Private memory declarations
113 *************************************************************************************
114 ********************************************************************************** */
115
116 /* Array of initialization values for TSM Timing registers.
117 * Stored in the same order as the registers so that it can be copied easily.
118 */
119 static const uint32_t ble_tsm_init_blt [NUM_TSM_TIMING_REGS] =
120 {
121 TSM_REG_VALUE(PLL_REG_EN_RX_WD, PLL_REG_EN_RX_WU, PLL_REG_EN_TX_WD, PLL_REG_EN_TX_WU),
122 TSM_REG_VALUE(PLL_VCO_REG_EN_RX_WD, PLL_VCO_REG_EN_RX_WU, PLL_VCO_REG_EN_TX_WD, PLL_VCO_REG_EN_TX_WU),
123 TSM_REG_VALUE(PLL_QGEN_REG_EN_RX_WD, PLL_QGEN_REG_EN_RX_WU, PLL_QGEN_REG_EN_TX_WD, PLL_QGEN_REG_EN_TX_WU),
124 TSM_REG_VALUE(PLL_TCA_TX_REG_EN_RX_WD, PLL_TCA_TX_REG_EN_RX_WU, PLL_TCA_TX_REG_EN_TX_WD, PLL_TCA_TX_REG_EN_TX_WU),
125 TSM_REG_VALUE(ADC_REG_EN_RX_WD, ADC_REG_EN_RX_WU, ADC_REG_EN_TX_WD, ADC_REG_EN_TX_WU),
126 TSM_REG_VALUE(PLL_REF_CLK_EN_RX_WD, PLL_REF_CLK_EN_RX_WU, PLL_REF_CLK_EN_TX_WD, PLL_REF_CLK_EN_TX_WU),
127 TSM_REG_VALUE(ADC_CLK_EN_RX_WD, ADC_CLK_EN_RX_WU, ADC_CLK_EN_TX_WD, ADC_CLK_EN_TX_WU),
128 TSM_REG_VALUE(PLL_VCO_AUTOTUNE_RX_WD, PLL_VCO_AUTOTUNE_RX_WU, PLL_VCO_AUTOTUNE_TX_WD, PLL_VCO_AUTOTUNE_TX_WU),
129 TSM_REG_VALUE(PLL_CYCLE_SLIP_LD_EN_RX_WD, PLL_CYCLE_SLIP_LD_EN_RX_WU, PLL_CYCLE_SLIP_LD_EN_TX_WD, PLL_CYCLE_SLIP_LD_EN_TX_WU),
130 TSM_REG_VALUE(PLL_VCO_EN_RX_WD, PLL_VCO_EN_RX_WU, PLL_VCO_EN_TX_WD, PLL_VCO_EN_TX_WU),
131 TSM_REG_VALUE(PLL_VCO_BUF_RX_EN_RX_WD, PLL_VCO_BUF_RX_EN_RX_WU, PLL_VCO_BUF_RX_EN_TX_WD, PLL_VCO_BUF_RX_EN_TX_WU),
132 TSM_REG_VALUE(PLL_VCO_BUF_TX_EN_RX_WD, PLL_VCO_BUF_TX_EN_RX_WU, PLL_VCO_BUF_TX_EN_TX_WD, PLL_VCO_BUF_TX_EN_TX_WU),
133 TSM_REG_VALUE(PLL_PA_BUF_EN_RX_WD, PLL_PA_BUF_EN_RX_WU, PLL_PA_BUF_EN_TX_WD, PLL_PA_BUF_EN_TX_WU),
134 TSM_REG_VALUE(PLL_LDV_EN_RX_WD, PLL_LDV_EN_RX_WU, PLL_LDV_EN_TX_WD, PLL_LDV_EN_TX_WU),
135 TSM_REG_VALUE(PLL_RX_LDV_RIPPLE_MUX_EN_RX_WD, PLL_RX_LDV_RIPPLE_MUX_EN_RX_WU, PLL_RX_LDV_RIPPLE_MUX_EN_TX_WD, PLL_RX_LDV_RIPPLE_MUX_EN_TX_WU),
136 TSM_REG_VALUE(PLL_TX_LDV_RIPPLE_MUX_EN_RX_WD, PLL_TX_LDV_RIPPLE_MUX_EN_RX_WU, PLL_TX_LDV_RIPPLE_MUX_EN_TX_WD, PLL_TX_LDV_RIPPLE_MUX_EN_TX_WU),
137 TSM_REG_VALUE(PLL_FILTER_CHARGE_EN_RX_WD, PLL_FILTER_CHARGE_EN_RX_WU, PLL_FILTER_CHARGE_EN_TX_WD, PLL_FILTER_CHARGE_EN_TX_WU),
138 TSM_REG_VALUE(PLL_PHDET_EN_RX_WD, PLL_PHDET_EN_RX_WU, PLL_PHDET_EN_TX_WD, PLL_PHDET_EN_TX_WU),
139 TSM_REG_VALUE(QGEN25_EN_RX_WD, QGEN25_EN_RX_WU, QGEN25_EN_TX_WD, QGEN25_EN_TX_WU),
140 TSM_REG_VALUE(TX_EN_RX_WD, TX_EN_RX_WU, TX_EN_TX_WD, TX_EN_TX_WU),
141 TSM_REG_VALUE(ADC_EN_RX_WD, ADC_EN_RX_WU, ADC_EN_TX_WD, ADC_EN_TX_WU),
142 TSM_REG_VALUE(ADC_I_Q_EN_RX_WD, ADC_I_Q_EN_RX_WU, ADC_I_Q_EN_TX_WD, ADC_I_Q_EN_TX_WU),
143 TSM_REG_VALUE(ADC_DAC_EN_RX_WD, ADC_DAC_EN_RX_WU, ADC_DAC_EN_TX_WD, ADC_DAC_EN_TX_WU),
144 TSM_REG_VALUE(ADC_RST_EN_RX_WD, ADC_RST_EN_RX_WU, ADC_RST_EN_TX_WD, ADC_RST_EN_TX_WU),
145 TSM_REG_VALUE(BBF_EN_RX_WD, BBF_EN_RX_WU, BBF_EN_TX_WD, BBF_EN_TX_WU),
146 TSM_REG_VALUE(TCA_EN_RX_WD, TCA_EN_RX_WU, TCA_EN_TX_WD, TCA_EN_TX_WU),
147 TSM_REG_VALUE(PLL_DIG_EN_RX_WD, PLL_DIG_EN_RX_WU, PLL_DIG_EN_TX_WD, PLL_DIG_EN_TX_WU),
148 TSM_REG_VALUE(TX_DIG_EN_RX_WD, TX_DIG_EN_RX_WU, TX_DIG_EN_TX_WD, TX_DIG_EN_TX_WU),
149 TSM_REG_VALUE(RX_DIG_EN_RX_WD, RX_DIG_EN_RX_WU, RX_DIG_EN_TX_WD, RX_DIG_EN_TX_WU),
150 TSM_REG_VALUE(RX_INIT_RX_WD, RX_INIT_RX_WU, RX_INIT_TX_WD, RX_INIT_TX_WU),
151 TSM_REG_VALUE(SIGMA_DELTA_EN_RX_WD, SIGMA_DELTA_EN_RX_WU, SIGMA_DELTA_EN_TX_WD, SIGMA_DELTA_EN_TX_WU),
152 TSM_REG_VALUE(ZBDEM_RX_EN_RX_WD, ZBDEM_RX_EN_RX_WU, ZBDEM_RX_EN_TX_WD, ZBDEM_RX_EN_TX_WU),
153 TSM_REG_VALUE(DCOC_EN_RX_WD, DCOC_EN_RX_WU, DCOC_EN_TX_WD, DCOC_EN_TX_WU),
154 TSM_REG_VALUE(DCOC_INIT_EN_RX_WD, DCOC_INIT_EN_RX_WU, DCOC_INIT_EN_TX_WD, DCOC_INIT_EN_TX_WU),
155 TSM_REG_VALUE(FREQ_TARG_LD_EN_RX_WD, FREQ_TARG_LD_EN_RX_WU, FREQ_TARG_LD_EN_TX_WD, FREQ_TARG_LD_EN_TX_WU),
156 TSM_REG_VALUE(SAR_ADC_TRIG_EN_RX_WD, SAR_ADC_TRIG_EN_RX_WU, SAR_ADC_TRIG_EN_TX_WD, SAR_ADC_TRIG_EN_TX_WU),
157 TSM_REG_VALUE(TSM_SPARE0_EN_RX_WD, TSM_SPARE0_EN_RX_WU, TSM_SPARE0_EN_TX_WD, TSM_SPARE0_EN_TX_WU),
158 TSM_REG_VALUE(TSM_SPARE1_EN_RX_WD, TSM_SPARE1_EN_RX_WU, TSM_SPARE1_EN_TX_WD, TSM_SPARE1_EN_TX_WU),
159 TSM_REG_VALUE(TSM_SPARE2_EN_RX_WD, TSM_SPARE2_EN_RX_WU, TSM_SPARE2_EN_TX_WD, TSM_SPARE2_EN_TX_WU),
160 TSM_REG_VALUE(TSM_SPARE03_EN_RX_WD, TSM_SPARE03_EN_RX_WU, TSM_SPARE03_EN_TX_WD, TSM_SPARE03_EN_TX_WU),
161 TSM_REG_VALUE(GPIO0_TRIG_EN_RX_WD, GPIO0_TRIG_EN_RX_WU, GPIO0_TRIG_EN_TX_WD, GPIO0_TRIG_EN_TX_WU),
162 TSM_REG_VALUE(GPIO1_TRIG_EN_RX_WD, GPIO1_TRIG_EN_RX_WU, GPIO1_TRIG_EN_TX_WD, GPIO1_TRIG_EN_TX_WU),
163 TSM_REG_VALUE(GPIO2_TRIG_EN_RX_WD, GPIO2_TRIG_EN_RX_WU, GPIO2_TRIG_EN_TX_WD, GPIO2_TRIG_EN_TX_WU),
164 TSM_REG_VALUE(GPIO3_TRIG_EN_RX_WD, GPIO3_TRIG_EN_RX_WU, GPIO3_TRIG_EN_TX_WD, GPIO3_TRIG_EN_TX_WU),
165 };
166
167 /*! *********************************************************************************
168 *************************************************************************************
169 * Public functions
170 *************************************************************************************
171 ********************************************************************************** */
172
173 /* Frequency remap initialization performs any required init for both
174 * the LL and TSM registers to implement proper time sequences.
175 */
tsm_ll_timing_init(PHY_RADIO_T mode)176 void tsm_ll_timing_init(PHY_RADIO_T mode)
177 {
178 uint8_t i;
179 #if USE_RAM_TESTING
180 /* Test only code which places the timing values in a RAM array */
181 static uint32_t tsm_values_test[NUM_TSM_TIMING_REGS];
182 uint32_t * tsm_reg_ptr = &tsm_values_test[0];
183 #else
184 /* Normal operational code */
185 uint32_t * tsm_reg_ptr = (uint32_t *)&XCVR_TSM_TIMING00;
186 #endif
187
188 /* Setup TSM timing registers with time sequences for BLE unconditionally */
189 /* NOTE: This code depends on the array of init values being in the proper order! */
190 for (i=0;i<NUM_TSM_TIMING_REGS;i++)
191 {
192 *tsm_reg_ptr++ = ble_tsm_init_blt[i];
193 }
194
195 /* Now (if needed) adjust from BLE timings to Zigbee timings since they are VERY similar */
196 if (mode == ZIGBEE_RADIO)
197 {
198 /* TX_DIG_EN must be earlier for Zigbee */
199 XCVR_TSM_TIMING27 = TSM_REG_VALUE(TX_DIG_EN_RX_WD, TX_DIG_EN_RX_WU, TX_DIG_EN_TX_WD, TX_DIG_EN_TX_WU-ZB_TX_DIG_ADVANCE);
200
201 /* ZBDEM_RX_EN must be setup properly (it is disabled in BLE).
202 * It's timing is the same as RX_DIG_EN!
203 */
204 XCVR_TSM_TIMING31 = TSM_REG_VALUE(RX_DIG_EN_RX_WD, RX_DIG_EN_RX_WU, RX_DIG_EN_TX_WD, RX_DIG_EN_TX_WU);
205 }
206
207 /* Setup XCVR registers for END_OF_TX_WU, END_OF_TX_WD, END_OF_RX_WU, END_OF_RX_WD
208 * based on the sequence components defined for the TSM timing registers.
209 */
210 XCVR_END_OF_SEQ = END_OF_SEQ_VALUE;
211
212 if (mode == BLE_RADIO) /* Only do this when in BLE mode! */
213 {
214 /* Setup LL registers with adjustment for how early to start the TX or RX sequence */
215 *(volatile uint16_t *)(BLE_REG_BASE + TX_RX_ON_DELAY) = TX_RX_ON_DELAY_VALUE;
216 *(volatile uint16_t *)(BLE_REG_BASE + TX_RX_SYNTH_DELAY) = TX_RX_SYNTH_DELAY_VALUE;
217 }
218 }