fpga_spi.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528
  1. /* sd2snes - SD card based universal cartridge for the SNES
  2. Copyright (C) 2009-2010 Maximilian Rehkopf <otakon@gmx.net>
  3. AVR firmware portion
  4. Inspired by and based on code from sd2iec, written by Ingo Korb et al.
  5. See sdcard.c|h, config.h.
  6. FAT file system access based on code by ChaN, Jim Brain, Ingo Korb,
  7. see ff.c|h.
  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; version 2 of the License only.
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. GNU General Public License for more details.
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  18. fpga_spi.h: functions for SPI ctrl, SRAM interfacing and feature configuration
  19. */
  20. /*
  21. SPI commands
  22. cmd param function
  23. =============================================
  24. 0t bbhhll set address to 0xbbhhll
  25. t = target
  26. target: 0 = RAM
  27. 1 = MSU Audio buffer
  28. 2 = MSU Data buffer
  29. targets 1 & 2 only require 2 address bytes to
  30. be written.
  31. 10 bbhhll set SNES input address mask to 0xbbhhll
  32. 20 bbhhll set SRAM address mask to 0xbbhhll
  33. 3m - set mapper to m
  34. 0=HiROM, 1=LoROM, 2=ExHiROM, 6=SF96, 7=Menu
  35. 4s - trigger SD DMA (512b from SD to memory)
  36. s: Bit 2 = partial, Bit 1:0 = target
  37. target: see above
  38. 60 sssseeee set SD DMA partial transfer start+end
  39. ssss = start offset (msb first)
  40. eeee = end offset (msb first)
  41. 8p - read (RAM only)
  42. p: 0 = no increment after read
  43. 8 = increment after read
  44. 9p {xx}* write xx
  45. p: i-tt
  46. tt = target (see above)
  47. i = increment (see above)
  48. E0 ssrr set MSU-1 status register (=FPGA status [7:0])
  49. ss = bits to set in status register (1=set)
  50. rr = bits to reset in status register (1=reset)
  51. E1 - pause DAC
  52. E2 - resume/play DAC
  53. E3 - reset DAC playback pointer (0)
  54. E4 hhll set MSU read pointer
  55. E5 tt{7} set RTC (SPC7110 format + 1000s of year,
  56. nibbles packed)
  57. eg 0x20111210094816 is 2011-12-10, 9:48:16
  58. E6 ssrr set/reset BS-X status register [7:0]
  59. E7 - reset SRTC state
  60. E8 - reset DSP program and data ROM write pointers
  61. E9 hhmmllxxxx write+incr. DSP program ROM (xxxx=dummy writes)
  62. EA hhllxxxx write+incr. DSP data ROM (xxxx=dummy writes)
  63. EB - put DSP into reset
  64. EC - release DSP from reset
  65. ED - set feature enable bits (see below)
  66. EE - select memory (0: ROM (PSRAM), 1: RAM (SRAM))
  67. F0 - receive test token (to see if FPGA is alive)
  68. F1 - receive status (16bit, MSB first), see below
  69. F2 - get MSU data address (32bit, MSB first)
  70. F3 - get MSU audio track no. (16bit, MSB first)
  71. F4 - get MSU volume (8bit)
  72. FE - get SNES master clock frequency (32bit, MSB first)
  73. measured 1x/sec
  74. FF {xx}* echo (returns the sent data in the next byte)
  75. FPGA status word:
  76. bit function
  77. ==========================================================================
  78. 15 SD DMA busy (0=idle, 1=busy)
  79. 14 DAC read pointer MSB
  80. 13 MSU read pointer MSB
  81. 12 [TODO SD DMA CRC status (0=ok, 1=error); valid after bit 15 -> 0]
  82. 11 reserved (0)
  83. 10 reserved (0)
  84. 9 reserved (0)
  85. 8 reserved (0)
  86. 7 reserved (0)
  87. 6 reserved (0)
  88. 5 MSU1 Audio request from SNES
  89. 4 MSU1 Data request from SNES
  90. 3 reserved (0)
  91. 2 MSU1 Audio control status: 0=no repeat, 1=repeat
  92. 1 MSU1 Audio control status: 0=pause, 1=play
  93. 0 MSU1 Audio control request
  94. FPGA feature enable bits:
  95. bit function
  96. ==========================================================================
  97. 7 -
  98. 6 -
  99. 5 -
  100. 4 -
  101. 3 enable MSU1 registers
  102. 2 enable SRTC registers
  103. 1 enable ST0010 mapping
  104. 0 enable DSPx mapping
  105. */
  106. #include <arm/NXP/LPC17xx/LPC17xx.h>
  107. #include "bits.h"
  108. #include "fpga.h"
  109. #include "config.h"
  110. #include "uart.h"
  111. #include "spi.h"
  112. #include "fpga_spi.h"
  113. #include "timer.h"
  114. #include "sdnative.h"
  115. void fpga_spi_init(void) {
  116. spi_init(SPI_SPEED_FAST);
  117. BITBAND(FPGA_MCU_RDY_REG->FIODIR, FPGA_MCU_RDY_BIT) = 0;
  118. }
  119. void set_msu_addr(uint16_t address) {
  120. FPGA_SELECT();
  121. FPGA_TX_BYTE(0x02);
  122. FPGA_TX_BYTE((address>>8)&0xff);
  123. FPGA_TX_BYTE((address)&0xff);
  124. FPGA_DESELECT();
  125. }
  126. void set_dac_addr(uint16_t address) {
  127. FPGA_SELECT();
  128. FPGA_TX_BYTE(0x01);
  129. FPGA_TX_BYTE((address>>8)&0xff);
  130. FPGA_TX_BYTE((address)&0xff);
  131. FPGA_DESELECT();
  132. }
  133. void set_mcu_addr(uint32_t address) {
  134. FPGA_SELECT();
  135. FPGA_TX_BYTE(0x00);
  136. FPGA_TX_BYTE((address>>16)&0xff);
  137. FPGA_TX_BYTE((address>>8)&0xff);
  138. FPGA_TX_BYTE((address)&0xff);
  139. FPGA_DESELECT();
  140. }
  141. void set_saveram_mask(uint32_t mask) {
  142. FPGA_SELECT();
  143. FPGA_TX_BYTE(0x20);
  144. FPGA_TX_BYTE((mask>>16)&0xff);
  145. FPGA_TX_BYTE((mask>>8)&0xff);
  146. FPGA_TX_BYTE((mask)&0xff);
  147. FPGA_DESELECT();
  148. }
  149. void set_rom_mask(uint32_t mask) {
  150. FPGA_SELECT();
  151. FPGA_TX_BYTE(0x10);
  152. FPGA_TX_BYTE((mask>>16)&0xff);
  153. FPGA_TX_BYTE((mask>>8)&0xff);
  154. FPGA_TX_BYTE((mask)&0xff);
  155. FPGA_DESELECT();
  156. }
  157. void set_mapper(uint8_t val) {
  158. FPGA_SELECT();
  159. FPGA_TX_BYTE(0x30 | (val & 0x0f));
  160. FPGA_DESELECT();
  161. }
  162. uint8_t fpga_test() {
  163. FPGA_SELECT();
  164. FPGA_TX_BYTE(0xF0); /* TEST */
  165. FPGA_TX_BYTE(0x00); /* dummy */
  166. uint8_t result = FPGA_RX_BYTE();
  167. FPGA_DESELECT();
  168. return result;
  169. }
  170. uint16_t fpga_status() {
  171. FPGA_SELECT();
  172. FPGA_TX_BYTE(0xF1); /* STATUS */
  173. FPGA_TX_BYTE(0x00); /* dummy */
  174. uint16_t result = (FPGA_RX_BYTE()) << 8;
  175. result |= FPGA_RX_BYTE();
  176. FPGA_DESELECT();
  177. return result;
  178. }
  179. void fpga_set_sddma_range(uint16_t start, uint16_t end) {
  180. FPGA_SELECT();
  181. FPGA_TX_BYTE(0x60); /* DMA_RANGE */
  182. FPGA_TX_BYTE(start>>8);
  183. FPGA_TX_BYTE(start&0xff);
  184. FPGA_TX_BYTE(end>>8);
  185. FPGA_TX_BYTE(end&0xff);
  186. //if(tgt==1 && (test=FPGA_RX_BYTE()) != 0x41) printf("!!!!!!!!!!!!!!! -%02x- \n", test);
  187. FPGA_DESELECT();
  188. }
  189. void fpga_sddma(uint8_t tgt, uint8_t partial) {
  190. uint32_t test = 0;
  191. uint8_t status = 0;
  192. BITBAND(SD_CLKREG->FIODIR, SD_CLKPIN) = 0;
  193. FPGA_SELECT();
  194. FPGA_TX_BYTE(0x40 | (tgt & 0x3) | ((partial & 1) << 2) ); /* DO DMA */
  195. FPGA_TX_BYTE(0x00); /* dummy for falling DMA_EN edge */
  196. //if(tgt==1 && (test=FPGA_RX_BYTE()) != 0x41) printf("!!!!!!!!!!!!!!! -%02x- \n", test);
  197. FPGA_DESELECT();
  198. FPGA_SELECT();
  199. FPGA_TX_BYTE(0xF1); /* STATUS */
  200. FPGA_TX_BYTE(0x00); /* dummy */
  201. DBG_SD printf("FPGA DMA request sent, wait for completion...");
  202. while((status=FPGA_RX_BYTE()) & 0x80) {
  203. FPGA_RX_BYTE(); /* eat the 2nd status byte */
  204. test++;
  205. }
  206. DBG_SD printf("...complete\n");
  207. FPGA_DESELECT();
  208. if(test<5)printf("loopy: %ld %02x\n", test, status);
  209. BITBAND(SD_CLKREG->FIODIR, SD_CLKPIN) = 1;
  210. }
  211. void set_dac_vol(uint8_t volume) {
  212. FPGA_SELECT();
  213. FPGA_TX_BYTE(0x50);
  214. FPGA_TX_BYTE(volume);
  215. FPGA_TX_BYTE(0x00); /* latch rise */
  216. FPGA_TX_BYTE(0x00); /* latch fall */
  217. FPGA_DESELECT();
  218. }
  219. void dac_play() {
  220. FPGA_SELECT();
  221. FPGA_TX_BYTE(0xe2);
  222. FPGA_TX_BYTE(0x00); /* latch reset */
  223. FPGA_DESELECT();
  224. }
  225. void dac_pause() {
  226. FPGA_SELECT();
  227. FPGA_TX_BYTE(0xe1);
  228. FPGA_TX_BYTE(0x00); /* latch reset */
  229. FPGA_DESELECT();
  230. }
  231. void dac_reset() {
  232. FPGA_SELECT();
  233. FPGA_TX_BYTE(0xe3);
  234. FPGA_TX_BYTE(0x00); /* latch reset */
  235. FPGA_TX_BYTE(0x00); /* latch reset */
  236. FPGA_DESELECT();
  237. }
  238. void msu_reset(uint16_t address) {
  239. FPGA_SELECT();
  240. FPGA_TX_BYTE(0xe4);
  241. FPGA_TX_BYTE((address>>8) & 0xff); /* address hi */
  242. FPGA_TX_BYTE(address & 0xff); /* address lo */
  243. FPGA_TX_BYTE(0x00); /* latch reset */
  244. FPGA_TX_BYTE(0x00); /* latch reset */
  245. FPGA_DESELECT();
  246. }
  247. void set_msu_status(uint8_t set, uint8_t reset) {
  248. FPGA_SELECT();
  249. FPGA_TX_BYTE(0xe0);
  250. FPGA_TX_BYTE(set);
  251. FPGA_TX_BYTE(reset);
  252. FPGA_TX_BYTE(0x00); /* latch reset */
  253. FPGA_DESELECT();
  254. }
  255. uint8_t get_msu_volume() {
  256. FPGA_SELECT();
  257. FPGA_TX_BYTE(0xF4); /* MSU_VOLUME */
  258. FPGA_TX_BYTE(0x00); /* dummy */
  259. uint8_t result = FPGA_RX_BYTE();
  260. FPGA_DESELECT();
  261. return result;
  262. }
  263. uint16_t get_msu_track() {
  264. FPGA_SELECT();
  265. FPGA_TX_BYTE(0xF3); /* MSU_TRACK */
  266. FPGA_TX_BYTE(0x00); /* dummy */
  267. uint16_t result = (FPGA_RX_BYTE()) << 8;
  268. result |= FPGA_RX_BYTE();
  269. FPGA_DESELECT();
  270. return result;
  271. }
  272. uint32_t get_msu_offset() {
  273. FPGA_SELECT();
  274. FPGA_TX_BYTE(0xF2); /* MSU_OFFSET */
  275. FPGA_TX_BYTE(0x00); /* dummy */
  276. uint32_t result = (FPGA_RX_BYTE()) << 24;
  277. result |= (FPGA_RX_BYTE()) << 16;
  278. result |= (FPGA_RX_BYTE()) << 8;
  279. result |= (FPGA_RX_BYTE());
  280. FPGA_DESELECT();
  281. return result;
  282. }
  283. uint32_t get_snes_romselclk() {
  284. FPGA_SELECT();
  285. FPGA_TX_BYTE(0xF7);
  286. FPGA_TX_BYTE(0x00); /* dummy */
  287. FPGA_TX_BYTE(0x00); /* dummy */
  288. uint32_t result = (FPGA_RX_BYTE()) << 24;
  289. result |= (FPGA_RX_BYTE()) << 16;
  290. result |= (FPGA_RX_BYTE()) << 8;
  291. result |= (FPGA_RX_BYTE());
  292. FPGA_DESELECT();
  293. return result;
  294. }
  295. uint32_t get_snes_cpuclk() {
  296. FPGA_SELECT();
  297. FPGA_TX_BYTE(0xF8);
  298. FPGA_TX_BYTE(0x00); /* dummy */
  299. FPGA_TX_BYTE(0x00); /* dummy */
  300. uint32_t result = (FPGA_RX_BYTE()) << 24;
  301. result |= (FPGA_RX_BYTE()) << 16;
  302. result |= (FPGA_RX_BYTE()) << 8;
  303. result |= (FPGA_RX_BYTE());
  304. FPGA_DESELECT();
  305. return result;
  306. }
  307. uint32_t get_snes_readclk() {
  308. FPGA_SELECT();
  309. FPGA_TX_BYTE(0xF9);
  310. FPGA_TX_BYTE(0x00); /* dummy */
  311. FPGA_TX_BYTE(0x00); /* dummy */
  312. uint32_t result = (FPGA_RX_BYTE()) << 24;
  313. result |= (FPGA_RX_BYTE()) << 16;
  314. result |= (FPGA_RX_BYTE()) << 8;
  315. result |= (FPGA_RX_BYTE());
  316. FPGA_DESELECT();
  317. return result;
  318. }
  319. uint32_t get_snes_writeclk() {
  320. FPGA_SELECT();
  321. FPGA_TX_BYTE(0xFA); /* GET_SYSCLK */
  322. FPGA_TX_BYTE(0x00); /* dummy */
  323. FPGA_TX_BYTE(0x00); /* dummy */
  324. uint32_t result = (FPGA_RX_BYTE()) << 24;
  325. result |= (FPGA_RX_BYTE()) << 16;
  326. result |= (FPGA_RX_BYTE()) << 8;
  327. result |= (FPGA_RX_BYTE());
  328. FPGA_DESELECT();
  329. return result;
  330. }
  331. uint32_t get_snes_pardclk() {
  332. FPGA_SELECT();
  333. FPGA_TX_BYTE(0xFB); /* GET_SYSCLK */
  334. FPGA_TX_BYTE(0x00); /* dummy */
  335. FPGA_TX_BYTE(0x00); /* dummy */
  336. uint32_t result = (FPGA_RX_BYTE()) << 24;
  337. result |= (FPGA_RX_BYTE()) << 16;
  338. result |= (FPGA_RX_BYTE()) << 8;
  339. result |= (FPGA_RX_BYTE());
  340. FPGA_DESELECT();
  341. return result;
  342. }
  343. uint32_t get_snes_pawrclk() {
  344. FPGA_SELECT();
  345. FPGA_TX_BYTE(0xFC); /* GET_SYSCLK */
  346. FPGA_TX_BYTE(0x00); /* dummy */
  347. FPGA_TX_BYTE(0x00); /* dummy */
  348. uint32_t result = (FPGA_RX_BYTE()) << 24;
  349. result |= (FPGA_RX_BYTE()) << 16;
  350. result |= (FPGA_RX_BYTE()) << 8;
  351. result |= (FPGA_RX_BYTE());
  352. FPGA_DESELECT();
  353. return result;
  354. }
  355. uint32_t get_snes_refreshclk() {
  356. FPGA_SELECT();
  357. FPGA_TX_BYTE(0xFD); /* GET_SYSCLK */
  358. FPGA_TX_BYTE(0x00); /* dummy */
  359. FPGA_TX_BYTE(0x00); /* dummy */
  360. uint32_t result = (FPGA_RX_BYTE()) << 24;
  361. result |= (FPGA_RX_BYTE()) << 16;
  362. result |= (FPGA_RX_BYTE()) << 8;
  363. result |= (FPGA_RX_BYTE());
  364. FPGA_DESELECT();
  365. return result;
  366. }
  367. uint32_t get_snes_sysclk() {
  368. FPGA_SELECT();
  369. FPGA_TX_BYTE(0xFE); /* GET_SYSCLK */
  370. FPGA_TX_BYTE(0x00); /* dummy */
  371. FPGA_TX_BYTE(0x00); /* dummy */
  372. uint32_t result = (FPGA_RX_BYTE()) << 24;
  373. result |= (FPGA_RX_BYTE()) << 16;
  374. result |= (FPGA_RX_BYTE()) << 8;
  375. result |= (FPGA_RX_BYTE());
  376. FPGA_DESELECT();
  377. return result;
  378. }
  379. void set_bsx_regs(uint8_t set, uint8_t reset) {
  380. FPGA_SELECT();
  381. FPGA_TX_BYTE(0xe6);
  382. FPGA_TX_BYTE(set);
  383. FPGA_TX_BYTE(reset);
  384. FPGA_TX_BYTE(0x00); /* latch reset */
  385. FPGA_DESELECT();
  386. }
  387. void set_fpga_time(uint64_t time) {
  388. FPGA_SELECT();
  389. FPGA_TX_BYTE(0xe5);
  390. FPGA_TX_BYTE((time >> 48) & 0xff);
  391. FPGA_TX_BYTE((time >> 40) & 0xff);
  392. FPGA_TX_BYTE((time >> 32) & 0xff);
  393. FPGA_TX_BYTE((time >> 24) & 0xff);
  394. FPGA_TX_BYTE((time >> 16) & 0xff);
  395. FPGA_TX_BYTE((time >> 8) & 0xff);
  396. FPGA_TX_BYTE(time & 0xff);
  397. FPGA_TX_BYTE(0x00);
  398. FPGA_DESELECT();
  399. }
  400. void fpga_reset_srtc_state() {
  401. FPGA_SELECT();
  402. FPGA_TX_BYTE(0xe7);
  403. FPGA_TX_BYTE(0x00);
  404. FPGA_TX_BYTE(0x00);
  405. FPGA_DESELECT();
  406. }
  407. void fpga_reset_dspx_addr() {
  408. FPGA_SELECT();
  409. FPGA_TX_BYTE(0xe8);
  410. FPGA_TX_BYTE(0x00);
  411. FPGA_TX_BYTE(0x00);
  412. FPGA_DESELECT();
  413. }
  414. void fpga_write_bram_data(uint8_t data) {
  415. FPGA_SELECT();
  416. FPGA_TX_BYTE(0xe9);
  417. FPGA_TX_BYTE(data);
  418. FPGA_TX_BYTE(0x00);
  419. FPGA_TX_BYTE(0x00);
  420. FPGA_DESELECT();
  421. }
  422. void fpga_write_dspx_dat(uint16_t data) {
  423. FPGA_SELECT();
  424. FPGA_TX_BYTE(0xea);
  425. FPGA_TX_BYTE((data>>8)&0xff);
  426. FPGA_TX_BYTE((data)&0xff);
  427. FPGA_TX_BYTE(0x00);
  428. FPGA_TX_BYTE(0x00);
  429. FPGA_DESELECT();
  430. }
  431. void fpga_dspx_reset(uint8_t reset) {
  432. FPGA_SELECT();
  433. FPGA_TX_BYTE(reset ? 0xeb : 0xec);
  434. FPGA_TX_BYTE(0x00);
  435. FPGA_DESELECT();
  436. }
  437. void fpga_set_features(uint8_t feat) {
  438. FPGA_SELECT();
  439. FPGA_TX_BYTE(0xed);
  440. FPGA_TX_BYTE(feat);
  441. FPGA_DESELECT();
  442. }
  443. void fpga_select_mem(uint8_t unit) {
  444. FPGA_SELECT();
  445. FPGA_TX_BYTE(0xee);
  446. FPGA_TX_BYTE(unit);
  447. FPGA_DESELECT();
  448. }
  449. void fpga_set_bram_addr(uint16_t addr) {
  450. FPGA_SELECT();
  451. FPGA_TX_BYTE(0xe8);
  452. FPGA_TX_BYTE((addr>>8)&0xff);
  453. FPGA_TX_BYTE((addr)&0xff);
  454. FPGA_TX_BYTE(0x00);
  455. FPGA_DESELECT();
  456. }
  457. uint8_t fpga_read_bram_data() {
  458. uint8_t data;
  459. FPGA_SELECT();
  460. FPGA_TX_BYTE(0xf5);
  461. FPGA_TX_BYTE(0x00);
  462. data = FPGA_RX_BYTE();
  463. FPGA_TX_BYTE(0x00);
  464. FPGA_DESELECT();
  465. return data;
  466. }