timings_RP2MCU.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702
  1. /**
  2. * ZuluSCSI™ - Copyright (c) 2024-2025 Rabbit Hole Computing™
  3. *
  4. * ZuluSCSI™ firmware is licensed under the GPL version 3 or any later version.
  5. *
  6. * https://www.gnu.org/licenses/gpl-3.0.html
  7. * ----
  8. * This program is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation, either version 3 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  20. **/
  21. #include "timings_RP2MCU.h"
  22. #include <string.h>
  23. #include "timings.h"
  24. #include <hardware/vreg.h>
  25. static bluescsi_timings_t predefined_timings[] = {
  26. // predefined_timings[0] - 125000000
  27. {
  28. .clk_hz = 125000000,
  29. .pll =
  30. {
  31. .refdiv = 1,
  32. .vco_freq = 1500000000,
  33. .post_div1 = 6,
  34. .post_div2 = 2
  35. },
  36. .scsi =
  37. {
  38. .req_delay = 7,
  39. .clk_period_ps = 8000
  40. },
  41. .scsi_20 =
  42. {
  43. .delay0 = 3 - 1,
  44. .delay1 = 4 - 1,
  45. .total_period_adjust = -1,
  46. .rdelay1 = 5 - 1,
  47. .rtotal_period_adjust = 0,
  48. .max_sync = 12,
  49. },
  50. .scsi_10 =
  51. {
  52. .delay0 = 5 - 1,
  53. .delay1 = 7 - 1,
  54. .total_period_adjust = -1,
  55. .rdelay1 = 6,
  56. .rtotal_period_adjust = 0,
  57. .max_sync = 25,
  58. },
  59. .scsi_5 =
  60. {
  61. .delay0 = 10 - 1,
  62. .delay1 = 15 - 1,
  63. .total_period_adjust = -1,
  64. .rdelay1 = 15 - 1,
  65. .rtotal_period_adjust = 0,
  66. .max_sync = 50,
  67. },
  68. .sdio =
  69. {
  70. .clk_div_1mhz = 25, // = 125MHz clk / clk_div_pio
  71. .clk_div_pio = 4,
  72. .delay0 = 3 - 1, // subtract one for the instruction delay
  73. .delay1 = 1 - 1 // clk_div_pio - delay0 and subtract one for the instruction delay
  74. },
  75. .audio =
  76. {
  77. .clk_div_pio = 48,
  78. .audio_clocked = false,
  79. }
  80. },
  81. // predefined_timings[1] - 133000000
  82. {
  83. .clk_hz = 133000000,
  84. .pll =
  85. {
  86. .refdiv = 1,
  87. .vco_freq = 1596000000,
  88. .post_div1 = 6,
  89. .post_div2 = 2
  90. },
  91. .scsi =
  92. {
  93. .req_delay = 7,
  94. .clk_period_ps = 7519
  95. },
  96. .scsi_20 =
  97. {
  98. .delay0 = 3 - 1,
  99. .delay1 = 4 - 1,
  100. .total_period_adjust = -1,
  101. .rdelay1 = 5 - 1,
  102. .rtotal_period_adjust = 1,
  103. .max_sync = 12,
  104. },
  105. .scsi_10 =
  106. {
  107. .delay0 = 5 - 1,
  108. .delay1 = 7 - 1,
  109. .total_period_adjust = -1,
  110. .rdelay1 = 7 - 1,
  111. .rtotal_period_adjust = 0,
  112. .max_sync = 25,
  113. },
  114. .scsi_5 =
  115. {
  116. .delay0 = 10 - 1,
  117. .delay1 = 15 - 1,
  118. .total_period_adjust = -1,
  119. .rdelay1 = 15 - 1,
  120. .rtotal_period_adjust = 0,
  121. .max_sync = 50,
  122. },
  123. .sdio =
  124. {
  125. .clk_div_1mhz = 25,
  126. .clk_div_pio = 5,
  127. .delay0 = 3 - 1, // subtract one for the instruction delay
  128. .delay1 = 2 - 1 // clk_div_pio - delay0 and subtract one for the instruction delay
  129. },
  130. .audio =
  131. {
  132. .clk_div_pio = 48,
  133. .audio_clocked = false,
  134. }
  135. },
  136. // predefined_timings[2] - 135428571 - RP2040 Audio DAC Attack S/PDIF clocks
  137. {
  138. .clk_hz = 135428571,
  139. .pll =
  140. {
  141. .refdiv = 1,
  142. .vco_freq = 948000000,
  143. .post_div1 = 7,
  144. .post_div2 = 1
  145. },
  146. .scsi =
  147. {
  148. .req_delay = 7,
  149. .clk_period_ps = 7384
  150. },
  151. .scsi_20 =
  152. {
  153. .delay0 = 3 - 1,
  154. .delay1 = 4 - 1,
  155. .total_period_adjust = -1,
  156. .rdelay1 = 5 - 1,
  157. .rtotal_period_adjust = 1,
  158. .max_sync = 12,
  159. },
  160. .scsi_10 =
  161. {
  162. .delay0 = 5 - 1,
  163. .delay1 = 7 - 1,
  164. .total_period_adjust = -1,
  165. .rdelay1 = 7 - 1,
  166. .rtotal_period_adjust = 0,
  167. .max_sync = 25,
  168. },
  169. .scsi_5 =
  170. {
  171. .delay0 = 10 - 1,
  172. .delay1 = 15 - 1,
  173. .total_period_adjust = -1,
  174. .rdelay1 = 15 - 1,
  175. .rtotal_period_adjust = 0,
  176. .max_sync = 50,
  177. },
  178. .sdio =
  179. {
  180. .clk_div_1mhz = 27 , // = 135MHz clk / clk_div_pio
  181. .clk_div_pio = 5,
  182. .delay0 = 3 - 1, // subtract one for the instruction delay
  183. .delay1 = 2 - 1 // clk_div_pio - delay0 and subtract one for the instruction delay
  184. },
  185. .audio =
  186. {
  187. // 44.1KHz to the nearest integer with a sys clk of 135.43MHz and 2 x 16-bit samples with the pio clock running 2x I2S clock
  188. // 135.43Mhz / 16 / 2 / 2 / 44.1KHz = 47.98 ~= 48
  189. .clk_div_pio = 48,
  190. .audio_clocked = true,
  191. }
  192. },
  193. // predefined_timings[3] - 150000000
  194. {
  195. .clk_hz = 150000000,
  196. .pll =
  197. {
  198. .refdiv = 1,
  199. .vco_freq = 1500000000,
  200. .post_div1 = 5,
  201. .post_div2 = 2
  202. },
  203. .scsi =
  204. {
  205. .req_delay = 9,
  206. .clk_period_ps = 6667
  207. },
  208. .scsi_20 =
  209. {
  210. .delay0 = 2 - 1,
  211. .delay1 = 4 - 1,
  212. .total_period_adjust = 0,
  213. .rdelay1 = 5 - 1,
  214. .rtotal_period_adjust = 1,
  215. .max_sync = 12,
  216. },
  217. .scsi_10 =
  218. {
  219. .delay0 = 4 - 1,
  220. .delay1 = 8 - 1,
  221. .total_period_adjust = 0,
  222. .rdelay1 = 8 - 1,
  223. .rtotal_period_adjust = 0,
  224. .max_sync = 25,
  225. },
  226. .scsi_5 =
  227. {
  228. .delay0 = 5 - 1,
  229. .delay1 = 8 - 1,
  230. .total_period_adjust = 0,
  231. .rdelay1 = 8 - 1,
  232. .rtotal_period_adjust = 0,
  233. .max_sync = 50,
  234. .clkdiv = 2,
  235. },
  236. .sdio =
  237. {
  238. .clk_div_1mhz = 30,// = 150MHz clk / clk_div_pio
  239. .clk_div_pio = 5,
  240. .delay0 = 3 - 1, // subtract one for the instruction delay
  241. .delay1 = 2 - 1 // clk_div_pio - delay0 and subtract one for the instruction delay
  242. },
  243. .audio =
  244. {
  245. .clk_div_pio = 54,
  246. .audio_clocked = false,
  247. }
  248. },
  249. // predefined_timings[4] - 250000000
  250. {
  251. .clk_hz = 250000000,
  252. .pll =
  253. {
  254. .refdiv = 1,
  255. .vco_freq = 1500000000,
  256. .post_div1 = 6,
  257. .post_div2 = 1
  258. },
  259. .scsi =
  260. {
  261. .req_delay = 14,
  262. .clk_period_ps = 4000,
  263. },
  264. .scsi_20 =
  265. {
  266. .delay0 = 3 - 1,
  267. .delay1 = 7 - 1,
  268. .total_period_adjust = 1,
  269. .rdelay1 = 7 - 1,
  270. .rtotal_period_adjust = 0,
  271. .max_sync = 12,
  272. },
  273. .scsi_10 =
  274. {
  275. .delay0 = 6 - 1,
  276. .delay1 = 12 - 1,
  277. .total_period_adjust = 0,
  278. .rdelay1 = 12 - 1,
  279. .rtotal_period_adjust = 0,
  280. .max_sync = 25,
  281. },
  282. .scsi_5 =
  283. {
  284. .delay0 = 8 - 1,
  285. .delay1 = 12 - 1,
  286. .total_period_adjust = 1,
  287. .rdelay1 = 12 - 1,
  288. .rtotal_period_adjust = 1,
  289. .max_sync = 50,
  290. .clkdiv = 2,
  291. },
  292. .sdio =
  293. {
  294. .clk_div_1mhz = 30,// set by trail and error
  295. .clk_div_pio = 5, // SDIO at 50MHz
  296. .delay0 = 4 - 1, // subtract one for the instruction delay
  297. .delay1 = 1 - 1 // clk_div_pio - delay0 and subtract one for the instruction delay
  298. },
  299. .audio =
  300. {
  301. // Divider for 44.1KHz to the nearest integer with a sys clk divided by 2 x 16-bit samples with the pio clock running 2x I2S clock
  302. // 200.4Mhz / 16 / 2 / 2 / 44.1KHz = 71.003 ~= 71
  303. .clk_div_pio = 89,
  304. .audio_clocked = false,
  305. }
  306. },
  307. // predefined_timings[5] - 155250000 - Default clocks for Blaster I2S Audio
  308. {
  309. .clk_hz = 155250000,
  310. .pll =
  311. {
  312. .refdiv = 3,
  313. .vco_freq = 1242000000,
  314. .post_div1 = 4,
  315. .post_div2 = 2,
  316. },
  317. .scsi =
  318. {
  319. .req_delay = 10,
  320. .clk_period_ps = 6441
  321. },
  322. .scsi_20 =
  323. {
  324. .delay0 = 2 - 1,
  325. .delay1 = 4 - 1,
  326. .total_period_adjust = 0,
  327. .rdelay1 = 5 - 1,
  328. .rtotal_period_adjust = 0,
  329. .max_sync = 12,
  330. },
  331. .scsi_10 =
  332. {
  333. .delay0 = 4 - 1,
  334. .delay1 = 7 - 1,
  335. .total_period_adjust = 0,
  336. .rdelay1 = 7 - 1,
  337. .rtotal_period_adjust = 0,
  338. .max_sync = 25,
  339. },
  340. .scsi_5 =
  341. {
  342. .delay0 = 5 - 1,
  343. .delay1 = 8 - 1,
  344. .total_period_adjust = 0,
  345. .rdelay1 = 8 - 1,
  346. .rtotal_period_adjust = 0,
  347. .max_sync = 50,
  348. .clkdiv = 2,
  349. },
  350. .sdio =
  351. {
  352. .clk_div_1mhz = 26, // = 155.25MHz clk / clk_div_pio
  353. .clk_div_pio = 6,
  354. .delay0 = 4 - 1, // subtract one for the instruction delay
  355. .delay1 = 2 - 1 // clk_div_pio - delay0 and subtract one for the instruction delay
  356. },
  357. .audio =
  358. {
  359. // 44.1KHz to the nearest integer with a sys clk of 155.25Mhz and 2 x 16-bit samples with the pio clock running 2x I2S clock
  360. // 155.25Mhz / 16 / 2 / 2 / 44.1KHz = 55.01 ~= 55
  361. .clk_div_pio = 55,
  362. .audio_clocked = true,
  363. }
  364. },
  365. // predefined_timings[6] - 175000000 - Alternate clocking for I2S Audio
  366. {
  367. // predefined_timings[6] - Clocking for I2S Audio at 175MHz system clock
  368. .clk_hz = 175000000,
  369. .pll =
  370. {
  371. .refdiv = 2,
  372. .vco_freq = 1050000000,
  373. .post_div1 = 6,
  374. .post_div2 = 1,
  375. },
  376. .scsi =
  377. {
  378. .req_delay = 10,
  379. .clk_period_ps = 5714
  380. },
  381. .scsi_20 =
  382. {
  383. .delay0 = 3 - 1,
  384. .delay1 = 5 - 1,
  385. .total_period_adjust = -1,
  386. .rdelay1 = 5 - 1,
  387. .rtotal_period_adjust = 1,
  388. .max_sync = 12,
  389. },
  390. .scsi_10 =
  391. {
  392. .delay0 = 4 - 1,
  393. .delay1 = 8 - 1,
  394. .total_period_adjust = 0,
  395. .rdelay1 = 8 - 1,
  396. .rtotal_period_adjust = 0,
  397. .max_sync = 25,
  398. },
  399. .scsi_5 =
  400. {
  401. .delay0 = 4 - 1,
  402. .delay1 = 8 - 1,
  403. .total_period_adjust = 0,
  404. .rdelay1 = 8 - 1,
  405. .rtotal_period_adjust = 0,
  406. .max_sync = 50,
  407. .clkdiv = 2,
  408. },
  409. .sdio =
  410. {
  411. .clk_div_1mhz = 30,
  412. .clk_div_pio = 5,
  413. .delay0 = 4 - 1, // subtract one for the instruction delay
  414. .delay1 = 1 - 1 // clk_div_pio - delay0 and subtract one for the instruction delay
  415. },
  416. .audio =
  417. {
  418. // Divider for 44.1KHz to the nearest integer with a sys clk divided by 2 x 16-bit samples with the pio clock running 2x I2S clock
  419. // 175Mhz / 16 / 2 / 2 / 44.1KHz ~= 62
  420. .clk_div_pio = 62,
  421. .audio_clocked = true,
  422. }
  423. },
  424. // predefined_timings[7] - 200400000 - Alternate clocking for I2S Audio
  425. {
  426. .clk_hz = 200400000,
  427. .pll =
  428. {
  429. .refdiv = 2,
  430. .vco_freq = 1002000000,
  431. .post_div1 = 5,
  432. .post_div2 = 1,
  433. },
  434. .scsi =
  435. {
  436. .req_delay = 12,
  437. .clk_period_ps = 4990
  438. },
  439. .scsi_20 =
  440. {
  441. .delay0 = 2 - 1,
  442. .delay1 = 5 - 1,
  443. .total_period_adjust = 0,
  444. .rdelay1 = 7 - 1,
  445. .rtotal_period_adjust = 1,
  446. .max_sync = 12,
  447. },
  448. .scsi_10 =
  449. {
  450. .delay0 = 5 - 1,
  451. .delay1 = 9 - 1,
  452. .total_period_adjust = 0,
  453. .rdelay1 = 9 - 1,
  454. .rtotal_period_adjust = 0,
  455. .max_sync = 25,
  456. },
  457. .scsi_5 =
  458. {
  459. .delay0 = 5 - 1,
  460. .delay1 = 10 - 1,
  461. .total_period_adjust = 0,
  462. .rdelay1 = 10 - 1,
  463. .rtotal_period_adjust = 0,
  464. .max_sync = 50,
  465. .clkdiv = 2,
  466. },
  467. .sdio =
  468. {
  469. .clk_div_1mhz = 30,
  470. .clk_div_pio = 5,
  471. .delay0 = 4 - 1, // subtract one for the instruction delay
  472. .delay1 = 1 - 1 // clk_div_pio - delay0 and subtract one for the instruction delay
  473. },
  474. .audio =
  475. {
  476. // Divider for 44.1KHz to the nearest integer with a sys clk divided by 2 x 16-bit samples with the pio clock running 2x I2S clock
  477. // 200.4Mhz / 16 / 2 / 2 / 44.1KHz = 71.003 ~= 71
  478. .clk_div_pio = 71,
  479. .audio_clocked = true,
  480. }
  481. },
  482. // predefined_timings[8] - 251200000 - Alternate clocking for I2S Audio
  483. {
  484. .clk_hz = 251200000,
  485. .pll =
  486. {
  487. .refdiv = 3,
  488. .vco_freq = 1256000000,
  489. .post_div1 = 5,
  490. .post_div2 = 1
  491. },
  492. .scsi =
  493. {
  494. .req_delay = 14,
  495. .clk_period_ps = 3981,
  496. },
  497. .scsi_20 =
  498. {
  499. .delay0 = 3 - 1,
  500. .delay1 = 7 - 1,
  501. .total_period_adjust = 1,
  502. .rdelay1 = 7 - 1,
  503. .rtotal_period_adjust = 0,
  504. .max_sync = 12,
  505. },
  506. .scsi_10 =
  507. {
  508. .delay0 = 6 - 1,
  509. .delay1 = 12 - 1,
  510. .total_period_adjust = 0,
  511. .rdelay1 = 12 - 1,
  512. .rtotal_period_adjust = 0,
  513. .max_sync = 25,
  514. },
  515. .scsi_5 =
  516. {
  517. .delay0 = 8 - 1,
  518. .delay1 = 12 - 1,
  519. .total_period_adjust = 1,
  520. .rdelay1 = 12 -1,
  521. .rtotal_period_adjust = 1,
  522. .max_sync = 50,
  523. .clkdiv = 2,
  524. },
  525. .sdio =
  526. {
  527. .clk_div_1mhz = 30,// set by trail and error
  528. .clk_div_pio = 5, // SDIO at 50MHz
  529. .delay0 = 4 - 1, // subtract one for the instruction delay
  530. .delay1 = 1 - 1 // clk_div_pio - delay0 and subtract one for the instruction delay
  531. },
  532. .audio =
  533. {
  534. // Divider for 44.1KHz to the nearest integer with a sys clk divided by 2 x 16-bit samples with the pio clock running 2x I2S clock
  535. // 200.4Mhz / 16 / 2 / 2 / 44.1KHz = 71.003 ~= 71
  536. .clk_div_pio = 89,
  537. .audio_clocked = true,
  538. }
  539. },
  540. };
  541. #ifdef ENABLE_AUDIO_OUTPUT_SPDIF
  542. bluescsi_timings_t *g_bluescsi_timings = &predefined_timings[2];
  543. #elif defined(ENABLE_AUDIO_OUTPUT_I2S)
  544. bluescsi_timings_t *g_bluescsi_timings = &predefined_timings[7];
  545. #elif defined(BLUESCSI_MCU_RP23XX)
  546. bluescsi_timings_t *g_bluescsi_timings = &predefined_timings[3];
  547. #elif defined(BLUESCSI_PICO)
  548. bluescsi_timings_t *g_bluescsi_timings = &predefined_timings[1];
  549. #else
  550. bluescsi_timings_t *g_bluescsi_timings = &predefined_timings[0];
  551. #endif
  552. bool set_timings(bluescsi_speed_grade_t speed_grade)
  553. {
  554. uint8_t timings_index = 0;
  555. switch (speed_grade)
  556. {
  557. #ifdef ENABLE_AUDIO_OUTPUT_I2S
  558. case SPEED_GRADE_MAX:
  559. case SPEED_GRADE_A:
  560. timings_index = 8;
  561. break;
  562. case SPEED_GRADE_B:
  563. timings_index = 6;
  564. break;
  565. case SPEED_GRADE_C:
  566. timings_index = 5;
  567. break;
  568. case SPEED_GRADE_AUDIO_SPDIF:
  569. timings_index = 2;
  570. break;
  571. case SPEED_GRADE_200MHZ:
  572. case SPEED_GRADE_AUDIO_I2S:
  573. timings_index = 7;
  574. break;
  575. case SPEED_GRADE_WIFI_RM2:
  576. timings_index = 5;
  577. #elif defined(BLUESCSI_MCU_RP23XX)
  578. case SPEED_GRADE_MAX:
  579. case SPEED_GRADE_A:
  580. timings_index = 4;
  581. break;
  582. case SPEED_GRADE_200MHZ:
  583. case SPEED_GRADE_B:
  584. timings_index = 7;
  585. break;
  586. case SPEED_GRADE_C:
  587. timings_index = 6;
  588. break;
  589. case SPEED_GRADE_AUDIO_SPDIF:
  590. timings_index = 2;
  591. break;
  592. case SPEED_GRADE_AUDIO_I2S:
  593. timings_index = 5;
  594. break;
  595. #else
  596. case SPEED_GRADE_MAX:
  597. case SPEED_GRADE_A:
  598. timings_index = 4;
  599. break;
  600. case SPEED_GRADE_B:
  601. timings_index = 3;
  602. break;
  603. case SPEED_GRADE_C:
  604. timings_index = 1;
  605. break;
  606. case SPEED_GRADE_AUDIO_SPDIF:
  607. timings_index = 2;
  608. break;
  609. case SPEED_GRADE_AUDIO_I2S:
  610. timings_index = 5;
  611. break;
  612. case SPEED_GRADE_200MHZ:
  613. timings_index = 7;
  614. #endif
  615. default:
  616. break;
  617. }
  618. if (speed_grade != SPEED_GRADE_DEFAULT && speed_grade != SPEED_GRADE_CUSTOM)
  619. {
  620. memcpy(g_bluescsi_timings, &predefined_timings[timings_index], sizeof(*g_bluescsi_timings));
  621. g_max_sync_10_period = g_bluescsi_timings->scsi_10.max_sync;
  622. g_max_sync_20_period = g_bluescsi_timings->scsi_20.max_sync;
  623. g_max_sync_5_period = g_bluescsi_timings->scsi_5.max_sync;
  624. return true;
  625. }
  626. return false;
  627. }