SIMULINK_A7DAC  1.0
Control of A7_DAC device
tf_pll.cpp
Go to the documentation of this file.
1 
2 //#include <QtTest/QTest>
3 
4 #include <stdio.h>
5 #include "stdafx.h"
6 
7 #define _USE_MATH_DEFINES
8 #include <math.h>
9 
10 #include "tf_pll.h"
11 #include "cl_reg.h"
12 //#include "gipcy.h"
13 
15 {
16  //! Доступ к регистрам модуля
18 
19  double freqSynt;
20  double freqClkA;
21  double freqClkB;
22 
23  int divA;
24  int divB;
25 
26 };
27 
28 
30 {
31  td = new TF_PLL_TaskData();
32 
33  td->reg = reg;
34 
35  td->divA=2;
36  td->divB=2;
37 }
38 
40 {
41  delete td; td=NULL;
42 
43 }
44 
45 //! Подготовка PLL
46 void TF_PLL::Prepare( void )
47 {
48  printf( "Подготовка PLL\n");
49 
50  td->reg->PkgCmdStart();
51  td->reg->PkgCmdWrite( 0, 8, 3 );
52  td->reg->PkgCmdWrite( 0, 9, 0xF4 );
53 
54 // td->reg->PkgCmdWrite( 1, 0, 0x00312815);
55 // td->reg->PkgCmdWrite( 1, 0, 0x40870010 );
56 // td->reg->PkgCmdWrite( 1, 0, 0x021FE80F);
57 // td->reg->PkgCmdWrite( 1, 0, 0x4082C10D);
58 // td->reg->PkgCmdWrite( 1, 0, 0x210050CA );
59 // td->reg->PkgCmdWrite( 1, 0, 0x03C7C039);
60 // td->reg->PkgCmdWrite( 1, 0, 0x207DDBF8);
61 // td->reg->PkgCmdWrite( 1, 0, 0x00082317);
62 // td->reg->PkgCmdWrite( 1, 0, 0x000004C6);
63 // td->reg->PkgCmdWrite( 1, 0, 0x00312805);
64 // td->reg->PkgCmdWrite( 1, 0, 0x00000004);
65 // td->reg->PkgCmdWrite( 1, 0, 0x201CF3C3 );
66 // td->reg->PkgCmdWrite( 1, 0, 0x0FD09002 );
67 // td->reg->PkgCmdWrite( 1, 0, 0xC4002051 );
68 // td->reg->PkgCmdWrite( 1, 0, 0x40960000 );
69 
70  td->reg->PkgCmdExecute();
71 
72 // //Sleep( 100 );
73 
74 // td->reg->PkgCmdStart();
75 // td->reg->PkgCmdWrite( 1, 0, 0x40960000 );
76 // td->reg->PkgCmdExecute();
77 
78  printf( "Подготовка PLL завершена\n");
79 
80  int freq=0;
81  int reg0x10=0;
82  // for( int ii=0; ii<100; ii++ )
83  {
84  td->reg->PkgCmdStart();
85  td->reg->PkgCmdRead( 0, 0x10, &reg0x10 );
86  td->reg->PkgCmdRead( 0, 0x11, &freq );
87  td->reg->PkgCmdExecute();
88 
89 
90  printf( "reg0x10=0x%.4X freq=%d \n", reg0x10, freq );
91  //for( volatile int jj=0; jj<1000000; jj++ );
92 
93  }
94 }
95 
96 //! Установка тактовой частоты
97 int TF_PLL::SetPll(double freq, double *pFreqOut)
98 {
99 
100  double dFreqIn = 100000000.0;
101 
102  //
103  // Проверить входные параметры
104  //
105  if( (dFreqIn < 5.0*1000.0*1000.0) ||
106  (dFreqIn > 900.0*1000.0*1000.0) ||
107  (freq < 47.368*1000.0*1000.0) ||
108  (freq > 3800.0*1000.0*1000.0) )
109  return 1;
110 
111  //
112  // Рассчитать коэффициенты деления R, N, D
113  //
114  int rr, nn, dd;
115  int nKeeR, nKeeN, nKeeD;
116  int isBreak;
117  double dFpfd, dFvco, dFclk, dDelta;
118  double dKeeDelta;
119 
120  //dKeeDelta = 1.0 * (*pFreqOut);
121  dKeeDelta = 1.0 * freq;
122 
123  nKeeR = nKeeN = nKeeD = 0;
124  isBreak = 0;
125 
126  for( rr=1; rr<=255; rr++ )
127  {
128  dFpfd = dFreqIn / rr;
129  if( (dFpfd < 5.0*1000.0*1000.0) ||
130  (dFpfd > 200.0*1000.0*1000.0) )
131  continue;
132  for( nn=4095; nn>=7; nn-- )
133  {
134  dFvco = dFpfd * nn;
135  if( (dFvco < 1800.0*1000.0*1000.0) ||
136  (dFvco > 3800.0*1000.0*1000.0) )
137  continue;
138  for( dd=38; dd>=1; dd-=(dd==2)?1:2 )
139  {
140  dFclk = dFvco / dd;
141  dDelta = fabs( dFclk-(freq) );
142  if( dDelta < dKeeDelta )
143  {
144  nKeeR = rr;
145  nKeeN = nn;
146  nKeeD = dd;
147  dKeeDelta = dDelta;
148  }
149  if( 1.0 > dKeeDelta )
150  {
151  isBreak = 1;
152  break;
153  }
154  }
155  if( isBreak )
156  break;
157  }
158  if( isBreak )
159  break;
160  }
161  if( 0==nKeeR || 0==nKeeN || 0==nKeeD )
162  return 1;
163 
164  dFclk = dFreqIn * nKeeN / nKeeR / nKeeD;
165 
166  printf( "TF_PLL::SetPll) >>>> R=%d, N=%d, D=%d\n Fclk_req=%15.0f Hz\n Fclk_set=%15.0f Hz\n delta=%17.0f Hz\n",
167  nKeeR, nKeeN, nKeeD, freq, dFclk, dKeeDelta );
168 
169  *pFreqOut = dFclk;
170  td->freqSynt = dFclk;
171  td->freqClkA = td->freqSynt / td->divA;
172  td->freqClkB = td->freqSynt / td->divB;
173 
174  //
175  // Запрограммировать микросхему PLL LMX2581
176  //
177  unsigned int nR5, nR3, nR1, nR0, code;
178 
179  nR0 = 0x04000000 | (nKeeN<<12);
180  nR1 = 0x0C400200 | (nKeeR&0xFF);
181  nR3 = 0x02000FBA;
182  nR5 = 0x00000A00;
183  if( nKeeD > 1 )
184  {
185  nR3 |= ((nKeeD-2)/2) << 14;
186  nR5 |= 1<<7;
187  }
188  if( dFreqIn<64.0*1000.0*1000.0) code = 0;
189  else if( dFreqIn<128.0*1000.0*1000.0) code = 1;
190  else if( dFreqIn<256.0*1000.0*1000.0) code = 2;
191  else if( dFreqIn<512.0*1000.0*1000.0) code = 3;
192  else code = 4;
193  nR5 |= code<<17;
194 
195  // DBG_printf(_BRDC("\n"));
196 
197 // DBG_SpdWrite(pModule, SPDdev_TRDS_SYNT, 0x05, 0x00000A81 ); //
198 // DBG_SpdWrite(pModule, SPDdev_TRDS_SYNT, 0x0F, 0x0021FE80 ); //
199 // DBG_SpdWrite(pModule, SPDdev_TRDS_SYNT, 0x0D, 0x04082C10 ); //
200 // DBG_SpdWrite(pModule, SPDdev_TRDS_SYNT, 0x0A, 0x0210050C ); //
201 // DBG_SpdWrite(pModule, SPDdev_TRDS_SYNT, 0x09, 0x003C7C03 ); //
202 // DBG_SpdWrite(pModule, SPDdev_TRDS_SYNT, 0x08, 0x0207DDBF ); //
203 // DBG_SpdWrite(pModule, SPDdev_TRDS_SYNT, 0x07, 0x00008233 ); //
204 // DBG_SpdWrite(pModule, SPDdev_TRDS_SYNT, 0x06, 0x0000004C ); //
205 // DBG_SpdWrite(pModule, SPDdev_TRDS_SYNT, 0x05, nR5 ); // Управление диапазонами частоты опорного сигнала
206 // DBG_SpdWrite(pModule, SPDdev_TRDS_SYNT, 0x04, 0x00000000 ); //
207 // DBG_SpdWrite(pModule, SPDdev_TRDS_SYNT, 0x03, nR3 ); // Значение делителя D
208 // DBG_SpdWrite(pModule, SPDdev_TRDS_SYNT, 0x02, 0x00FD0900 ); //
209 // DBG_SpdWrite(pModule, SPDdev_TRDS_SYNT, 0x01, nR1 ); // Значение делителя R
210 // DBG_SpdWrite(pModule, SPDdev_TRDS_SYNT, 0x00, nR0 ); // Значение делителя N
211 
212 
213  td->reg->PkgCmdStart();
214 
215 
216  SpdWrite( 0x05, 0x0031281 ); //
217  SpdWrite( 0x0F, 0x0021FE80 ); //
218  SpdWrite( 0x0D, 0x04082C10 ); //
219  SpdWrite( 0x0A, 0x0210050C ); //
220  SpdWrite( 0x09, 0x003C7C03 ); //
221  SpdWrite( 0x08, 0x0207DDBF ); //
222  SpdWrite( 0x07, 0x00008233 ); //
223  SpdWrite( 0x06, 0x0000004C ); //
224  SpdWrite( 0x05, nR5 ); // Управление диапазонами частоты опорного сигнала
225  SpdWrite( 0x04, 0x00000000 ); //
226  SpdWrite( 0x03, nR3 ); // Значение делителя D
227  SpdWrite( 0x02, 0x00FD0900 ); //
228  SpdWrite( 0x01, nR1 ); // Значение делителя R
229  SpdWrite( 0x00, nR0 ); // Значение делителя N
230 
231  td->reg->PkgCmdExecute();
232 
233  //QTest::qSleep( 100 );
234  //IPC_delay( 100 );
235  Sleep( 100 );
236 
237  //RealDelay( 20, 1 );
238  //DBG_SpdWrite(pModule, SPDdev_TRDS_SYNT, 0x00, nR0 ); // Значение делителя N
239 
240  td->reg->PkgCmdStart();
241  SpdWrite( 0x00, nR0 ); // Значение делителя N
242  td->reg->PkgCmdExecute();
243 
244  return 0;
245 }
246 
247 //! Запись в регистр синтезатора
248 void TF_PLL::SpdWrite( unsigned int adr, unsigned int data )
249 {
250  int d = (data << 4 ) | adr;
251 
252  td->reg->PkgCmdWrite( 1, 0, d );
253 }
254 
255 //! Установка делителей
256 void TF_PLL::SetDiv( int divA, int divB )
257 {
258  int valA, valB, val;
259 
260  switch( divA )
261  {
262  case 2: valA = 0; break;
263  case 4: valA = 1; break;
264  case 8: valA = 2; break;
265  default: valA = 3; break;
266  }
267 
268  switch( divB )
269  {
270  case 2: valB = 0; break;
271  case 4: valB = 1; break;
272  case 8: valB = 2; break;
273  default: valB = 3; break;
274  }
275 
276  val = 0x44 | valB<<4 | valA;
277 
278  td->divA=divA;
279  td->divB=divB;
280 
281  td->freqClkA = td->freqSynt / td->divA;
282  td->freqClkB = td->freqSynt / td->divB;
283 
284  td->reg->PkgCmdStart();
285  td->reg->PkgCmdWrite( 0, 9, val );
286  td->reg->PkgCmdExecute();
287  printf( "%s val = 0x%.2X\n", __FUNCTION__, val);
288 }
289 
290 //! Установленное значение частоты
291 double TF_PLL::GetFreq( int n )
292 {
293  double ret=0;
294  switch( n )
295  {
296  case 0: ret=td->freqSynt/1000000.0; break;
297  case 1: ret=td->freqClkA/1000000.0; break;
298  case 2: ret=td->freqClkB/1000000.0; break;
299  }
300  return ret;
301 }
virtual void PkgCmdRead(int dev, int adr, int *pData)
Чтение из регистра
Definition: cl_reg.h:28
void SetDiv(int divA, int divB)
Установка делителей
Definition: tf_pll.cpp:256
virtual void PkgCmdStart(void)
Начало выполнения команды
Definition: cl_reg.h:22
double GetFreq(int n)
Установленное значение частоты
Definition: tf_pll.cpp:291
virtual ~TF_PLL()
Definition: tf_pll.cpp:39
virtual void PkgCmdExecute(void)
Выполнение команды
Definition: cl_reg.h:31
double freqClkA
Definition: tf_pll.cpp:20
CL_Reg * reg
Доступ к регистрам модуля
Definition: tf_pll.cpp:17
virtual void PkgCmdWrite(int dev, int adr, int data)
Запись в регистр
Definition: cl_reg.h:25
double freqClkB
Definition: tf_pll.cpp:21
Доступ к регистраи
Definition: cl_reg.h:13
double freqSynt
Definition: tf_pll.cpp:19
int SetPll(double freq, double *pFreqOut)
Установка тактовой частоты
Definition: tf_pll.cpp:97
TF_PLL(CL_Reg *reg)
Definition: tf_pll.cpp:29
void SpdWrite(unsigned int adr, unsigned int data)
Запись в регистр синтезатора
Definition: tf_pll.cpp:248
TF_PLL_TaskData * td
Внутренние данные класса
Definition: tf_dac.h:18
void Prepare(void)
Подготовка PLL.
Definition: tf_pll.cpp:46