ad9912.c 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. #include "ad9912.h"
  2. #include <math.h>
  3. uint32_t ad9912regs[AD9912_COUNT] = {
  4. 0x000018,
  5. 0x000100,
  6. 0x000202,
  7. 0x000309,
  8. 0x000400,
  9. 0x000500,
  10. 0x001010,
  11. 0x001200,
  12. 0x001300,
  13. 0x002012,
  14. 0x002204,
  15. 0x010400,
  16. 0x010500,
  17. 0x010600,
  18. 0x01A633,
  19. 0x01A733,
  20. 0x01A833,
  21. 0x01A933,
  22. 0x01AA33,
  23. 0x01AB33,
  24. 0x01AC00,
  25. 0x01AD00,
  26. 0x020005,
  27. 0x020100,
  28. 0x040BFF,
  29. 0x040C01,
  30. 0x040E10,
  31. 0x050000,
  32. 0x050100,
  33. 0x050200,
  34. 0x050300,
  35. 0x050400,
  36. 0x050500,
  37. 0x050600,
  38. 0x050700,
  39. 0x050800,
  40. 0x050900
  41. };
  42. uint32_t ad9912_ftw_regs_qspi[4];
  43. /*-------------------------AD9912 INIT FUNCTION-------------------------*/
  44. void ad9912_init(void *bar1) {
  45. uint32_t *ptr_rst = bar1 + TMSG_BASE_ADDR;
  46. *ptr_rst = GPIO_INIT_HEADER;
  47. //Rst on
  48. *ptr_rst = AD9912_RST_ON;
  49. // Rst off
  50. *ptr_rst = GPIO_REG;
  51. //Init Header
  52. uint32_t *ptr = bar1 + TMSG_BASE_ADDR;
  53. *ptr = InitDDSHeader;
  54. //Init Data
  55. for (int k = 0; k < AD9912_COUNT; k++) {
  56. uint32_t *ptr = bar1 + TMSG_BASE_ADDR;
  57. *ptr = ad9912regs[k];
  58. }
  59. }
  60. /*----------------------------------------------------------------------*/
  61. double ad9912_set_main_band(double lmx_freq,double f_pd) {
  62. // Divide the frequncy by the old value of the phase detector frequency and only left with the integer part
  63. uint32_t N = (uint32_t) (lmx_freq/f_pd);
  64. if (f_pd >= 300e6) {
  65. N = N+10;
  66. }
  67. if (lmx_freq <= 12500e6) {
  68. if (N < 28){
  69. N= 28;
  70. };
  71. }
  72. else if (lmx_freq > 12500e6) {
  73. if (N <32) {
  74. N = 32;
  75. }
  76. };
  77. printf("N = %d\n", N);
  78. // Calculate the new phase detector frequency by dividing the frequency by the new value of N
  79. f_pd = lmx_freq/N; // Phase detector frequency
  80. return f_pd;
  81. }
  82. double ad9912_set_out_of_band(double lmx_freq,double f_pd) {
  83. double f_vco = 2*lmx_freq; // VCO frequency
  84. double vco_div = 7.5e9/lmx_freq;
  85. int chan_div = 2;
  86. if (f_vco < 7.5e9) {
  87. if (vco_div > 2 && vco_div <= 4) {
  88. chan_div = 4; // 4
  89. f_vco = lmx_freq * chan_div;
  90. }
  91. else if (vco_div > 4 && vco_div <= 6) {
  92. chan_div = 6; // 6
  93. f_vco = lmx_freq * chan_div;
  94. }
  95. else if (vco_div > 6 && vco_div <= 8) {
  96. chan_div = 8; // 8
  97. f_vco = lmx_freq * chan_div;
  98. }
  99. else if (vco_div > 8 && vco_div <= 12) {
  100. chan_div = 12; // 12
  101. f_vco = lmx_freq * chan_div;
  102. }
  103. else if (vco_div > 12 && vco_div <= 16) {
  104. chan_div = 16; // 16
  105. f_vco = lmx_freq * chan_div;
  106. }
  107. else if (vco_div > 16 && vco_div <= 24) {
  108. chan_div = 24; // 24
  109. f_vco = lmx_freq * chan_div;
  110. }
  111. else if (vco_div > 24 && vco_div <= 32) {
  112. chan_div = 32; // 32
  113. f_vco = lmx_freq * chan_div;
  114. }
  115. else if (vco_div > 32 && vco_div <= 48) {
  116. chan_div = 48; // 48
  117. f_vco = lmx_freq * chan_div;
  118. }
  119. else if (vco_div > 48 && vco_div <= 64) {
  120. chan_div = 64; // 64
  121. f_vco = lmx_freq * chan_div;
  122. }
  123. else if (vco_div > 64 && vco_div <= 72) {
  124. chan_div = 72; // 72
  125. f_vco = lmx_freq * chan_div;
  126. }
  127. else if (vco_div > 72 && vco_div <= 96) {
  128. chan_div = 96; // 96
  129. f_vco = lmx_freq * chan_div;
  130. }
  131. else if (vco_div > 96 && vco_div <= 128) {
  132. chan_div = 128; // 128
  133. f_vco = lmx_freq * chan_div;
  134. }
  135. else if (vco_div > 128 && vco_div <= 192) {
  136. chan_div = 192; // 192
  137. f_vco = lmx_freq * chan_div;
  138. }
  139. else if (vco_div > 192 && vco_div <= 256) {
  140. chan_div = 256; // 256
  141. f_vco = lmx_freq * chan_div;
  142. }
  143. else if (vco_div > 256 && vco_div <= 384) {
  144. chan_div = 384; // 384
  145. f_vco = lmx_freq * chan_div;
  146. }
  147. else if (vco_div > 384 && vco_div <= 512) {
  148. chan_div = 512; // 512
  149. f_vco = lmx_freq * chan_div;
  150. }
  151. else if (vco_div > 512 && vco_div <= 768) {
  152. chan_div = 768; // 768
  153. f_vco = lmx_freq * chan_div;
  154. }
  155. }
  156. else {
  157. f_vco = lmx_freq * 2;
  158. }
  159. // Divide the frequncy by the old value of the phase detector frequency and only left with the integer part
  160. uint32_t N = (uint32_t) (f_vco/f_pd);
  161. if (f_pd >= 300e6) {
  162. N = N+10;
  163. }
  164. if (f_vco <= 12500e6) {
  165. if (N < 28){
  166. N= 28;
  167. };
  168. }
  169. else if (f_vco > 12500e6) {
  170. if (N <32) {
  171. N = 32;
  172. }
  173. };
  174. // Calculate the new phase detector frequency by dividing the frequency by the new value of N
  175. f_pd = f_vco/N; // Phase detector frequency
  176. return f_pd;
  177. }
  178. double ad9912_set(void *bar1, double freq, double f_pd) {
  179. double fs = 1e9;
  180. if (freq >= 7500e6 && freq <= 15000e6) {
  181. f_pd = ad9912_set_main_band(freq,f_pd);
  182. }
  183. else if (freq >= 10e6 && freq < 7500e6) {
  184. f_pd = ad9912_set_out_of_band(freq,f_pd);
  185. }
  186. else {
  187. return -1;
  188. printf("Frequency is out of range\n");
  189. }
  190. printf("f_pd = %f\n", f_pd);
  191. // FTW word
  192. double ftw_word = (f_pd*pow(2, 48))/fs;
  193. // Split the FTW word between 6 registers
  194. // First one is ftw_word[7:0]
  195. uint8_t ftw0_7_0 = (uint8_t) ftw_word;
  196. ad9912regs[REGP_AD9912_FTW0_FREQ_WORD_7_0] = ad9912regs[REGP_AD9912_FTW0_FREQ_WORD_7_0] & ~BITM_AD9912_FTW0_FREQ_WORD_7_0;
  197. ad9912regs[REGP_AD9912_FTW0_FREQ_WORD_7_0] = ad9912regs[REGP_AD9912_FTW0_FREQ_WORD_7_0] | (ftw0_7_0 << BITP_AD9912_FTW0_FREQ_WORD_7_0);
  198. // Second one is ftw_word[15:8]
  199. uint8_t ftw0_15_8 = (uint8_t) ((uint64_t)ftw_word >> 8);
  200. ad9912regs[REGP_AD9912_FTW0_FREQ_WORD_15_8] = ad9912regs[REGP_AD9912_FTW0_FREQ_WORD_15_8] & ~BITM_AD9912_FTW0_FREQ_WORD_15_8;
  201. ad9912regs[REGP_AD9912_FTW0_FREQ_WORD_15_8] = ad9912regs[REGP_AD9912_FTW0_FREQ_WORD_15_8] | (ftw0_15_8 << BITP_AD9912_FTW0_FREQ_WORD_15_8);
  202. // Third one is ftw_word[23:16]
  203. uint8_t ftw0_23_16 = (uint32_t) ((uint64_t)ftw_word >> 16);
  204. ad9912regs[REGP_AD9912_FTW0_FREQ_WORD_23_16] = ad9912regs[REGP_AD9912_FTW0_FREQ_WORD_23_16] & ~BITM_AD9912_FTW0_FREQ_WORD_23_16;
  205. ad9912regs[REGP_AD9912_FTW0_FREQ_WORD_23_16] = ad9912regs[REGP_AD9912_FTW0_FREQ_WORD_23_16] | (ftw0_23_16 << BITP_AD9912_FTW0_FREQ_WORD_23_16);
  206. // Fourth one is ftw_word[31:24]
  207. uint8_t ftw0_31_24 = (uint64_t) ((uint64_t)ftw_word >> 24);
  208. ad9912regs[REGP_AD9912_FTW0_FREQ_WORD_31_24] = ad9912regs[REGP_AD9912_FTW0_FREQ_WORD_31_24] & ~BITM_AD9912_FTW0_FREQ_WORD_31_24;
  209. ad9912regs[REGP_AD9912_FTW0_FREQ_WORD_31_24] = ad9912regs[REGP_AD9912_FTW0_FREQ_WORD_31_24] | (ftw0_31_24 << BITP_AD9912_FTW0_FREQ_WORD_31_24);
  210. // Fifth one is ftw_word[39:32]
  211. uint8_t ftw1_39_32 = (uint32_t) ((uint64_t)ftw_word >> 32);
  212. ad9912regs[REGP_AD9912_FTW0_FREQ_WORD_39_24] = ad9912regs[REGP_AD9912_FTW0_FREQ_WORD_39_24] & ~BITM_AD9912_FTW0_FREQ_WORD_39_24;
  213. ad9912regs[REGP_AD9912_FTW0_FREQ_WORD_39_24] = ad9912regs[REGP_AD9912_FTW0_FREQ_WORD_39_24] | (ftw1_39_32<< BITP_AD9912_FTW0_FREQ_WORD_39_24);
  214. // Sixth one is ftw_word[47:40]
  215. uint8_t ftw1_47_40 = (uint32_t) ((uint64_t)ftw_word >> 40);
  216. ad9912regs[REGP_AD9912_FTW0_FREQ_WORD_47_40] = ad9912regs[REGP_AD9912_FTW0_FREQ_WORD_47_40] & ~BITM_AD9912_FTW0_FREQ_WORD_47_40;
  217. ad9912regs[REGP_AD9912_FTW0_FREQ_WORD_47_40] = ad9912regs[REGP_AD9912_FTW0_FREQ_WORD_47_40] | (ftw1_47_40 << BITP_AD9912_FTW0_FREQ_WORD_47_40);
  218. // Set the frequency
  219. // uint32_t ad9912_ftw_regs[] = {
  220. // ad9912regs[REGP_AD9912_FTW0_FREQ_WORD_7_0],
  221. // ad9912regs[REGP_AD9912_FTW0_FREQ_WORD_15_8],
  222. // ad9912regs[REGP_AD9912_FTW0_FREQ_WORD_23_16],
  223. // ad9912regs[REGP_AD9912_FTW0_FREQ_WORD_31_24],
  224. // ad9912regs[REGP_AD9912_FTW0_FREQ_WORD_39_24],
  225. // ad9912regs[REGP_AD9912_FTW0_FREQ_WORD_47_40]
  226. // };
  227. // First 16 bits is the instruction word
  228. ad9912_ftw_regs_qspi[0] = (ENUM_AD9912_INSTRUCTION_WORD_WRITE | ENUM_AD9912_INSTRUCTION_WORD_STREAM | ENUM_ADD9912_INSTRUCTION_WORD_INIT_ADDR_9_12);
  229. ad9912_ftw_regs_qspi[1] = (ENUM_ADD9912_INSTRUCTION_WORD_INIT_ADDR_0_8 | (0x00 << BITP_AD9912_QSPI_PHASE_13_8) | (0x00 << BITP_AD9912_QSPI_PHASE_7_0));
  230. ad9912_ftw_regs_qspi[2] = ((ftw1_47_40 << BITP_AD9912_QSPI_47_40) | (ftw1_39_32 << BITP_AD9912_QSPI_39_32) | (ftw0_31_24 << BITP_AD9912_QSPI_31_24));
  231. ad9912_ftw_regs_qspi[3] = ((ftw0_23_16 << BITP_AD9912_QSPI_23_16) | (ftw0_15_8 << BITP_AD9912_QSPI_15_8) | (ftw0_7_0 << BITP_AD9912_QSPI_7_0));
  232. // // Create the appropriate header
  233. // uint32_t *dds_header = bar1 + TMSG_BASE_ADDR;
  234. // *dds_header = ((0 << 23) | (DeviceIdDDS << 18) | ((sizeof(ad9912_ftw_regs)/4) << 1) | 1);
  235. // uint32_t *dds_data = bar1 + TMSG_BASE_ADDR;
  236. // // Write the data
  237. // for (int i = 0; i < sizeof(ad9912_ftw_regs)/4; i++) {
  238. // *dds_data = ad9912_ftw_regs[i];
  239. // }
  240. return f_pd;
  241. }