fpga_spi.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  1. /* sd2snes - SD card based universal cartridge for the SNES
  2. Copyright (C) 2009-2012 Maximilian Rehkopf <otakon@gmx.net>
  3. uC 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 xsssyeee set SD DMA partial transfer parameters
  39. x: 0 = read from sector start (skip until
  40. start offset reached)
  41. 8 = assume mid-sector position and read
  42. immediately
  43. sss = start offset (msb first)
  44. y: 0 = skip rest of SD sector
  45. 8 = stop mid-sector if end offset reached
  46. eee = end offset (msb first)
  47. 8p - read (RAM only)
  48. p: 0 = no increment after read
  49. 8 = increment after read
  50. 9p {xx}* write xx
  51. p: i-tt
  52. tt = target (see above)
  53. i = increment (see above)
  54. E0 ssrr set MSU-1 status register (=FPGA status [7:0])
  55. ss = bits to set in status register (1=set)
  56. rr = bits to reset in status register (1=reset)
  57. E1 - pause DAC
  58. E2 - resume/play DAC
  59. E3 - reset DAC playback pointer (0)
  60. E4 hhll set MSU read pointer
  61. E5 tt{7} set RTC (SPC7110 format + 1000s of year,
  62. nibbles packed)
  63. eg 0x20111210094816 is 2011-12-10, 9:48:16
  64. E6 ssrr set/reset BS-X status register [7:0]
  65. E7 - reset SRTC state
  66. E8 - reset DSP program and data ROM write pointers
  67. E9 hhmmllxxxx write+incr. DSP program ROM (xxxx=dummy writes)
  68. EA hhllxxxx write+incr. DSP data ROM (xxxx=dummy writes)
  69. EB - put DSP into reset
  70. EC - release DSP from reset
  71. ED - set feature enable bits (see below)
  72. EE - set $213f override value (0=NTSC, 1=PAL)
  73. F0 - receive test token (to see if FPGA is alive)
  74. F1 - receive status (16bit, MSB first), see below
  75. F2 - get MSU data address (32bit, MSB first)
  76. F3 - get MSU audio track no. (16bit, MSB first)
  77. F4 - get MSU volume (8bit)
  78. FE - get SNES master clock frequency (32bit, MSB first)
  79. measured 1x/sec
  80. FF {xx}* echo (returns the sent data in the next byte)
  81. FPGA status word:
  82. bit function
  83. ==========================================================================
  84. 15 SD DMA busy (0=idle, 1=busy)
  85. 14 DAC read pointer MSB
  86. 13 MSU read pointer MSB
  87. 12 reserved (0)
  88. 11 reserved (0)
  89. 10 reserved (0)
  90. 9 reserved (0)
  91. 8 reserved (0)
  92. 7 reserved (0)
  93. 6 reserved (0)
  94. 5 MSU1 Audio request from SNES
  95. 4 MSU1 Data request from SNES
  96. 3 reserved (0)
  97. 2 MSU1 Audio control status: 0=no repeat, 1=repeat
  98. 1 MSU1 Audio control status: 0=pause, 1=play
  99. 0 MSU1 Audio control request
  100. FPGA feature enable bits:
  101. bit function
  102. ==========================================================================
  103. 7 -
  104. 6 -
  105. 5 -
  106. 4 enable $213F override
  107. 3 enable MSU1 registers
  108. 2 enable SRTC registers
  109. 1 enable ST0010 mapping
  110. 0 enable DSPx mapping
  111. */
  112. #include <arm/NXP/LPC17xx/LPC17xx.h>
  113. #include "bits.h"
  114. #include "fpga.h"
  115. #include "config.h"
  116. #include "uart.h"
  117. #include "spi.h"
  118. #include "fpga_spi.h"
  119. #include "timer.h"
  120. #include "sdnative.h"
  121. void fpga_spi_init( void )
  122. {
  123. spi_init();
  124. BITBAND( FPGA_MCU_RDY_REG->FIODIR, FPGA_MCU_RDY_BIT ) = 0;
  125. }
  126. void set_msu_addr( uint16_t address )
  127. {
  128. FPGA_SELECT();
  129. FPGA_TX_BYTE( FPGA_CMD_SETADDR | FPGA_TGT_MSUBUF );
  130. FPGA_TX_BYTE( ( address >> 8 ) & 0xff );
  131. FPGA_TX_BYTE( ( address ) & 0xff );
  132. FPGA_DESELECT();
  133. }
  134. void set_dac_addr( uint16_t address )
  135. {
  136. FPGA_SELECT();
  137. FPGA_TX_BYTE( FPGA_CMD_SETADDR | FPGA_TGT_DACBUF );
  138. FPGA_TX_BYTE( ( address >> 8 ) & 0xff );
  139. FPGA_TX_BYTE( ( address ) & 0xff );
  140. FPGA_DESELECT();
  141. }
  142. void set_mcu_addr( uint32_t address )
  143. {
  144. FPGA_SELECT();
  145. FPGA_TX_BYTE( FPGA_CMD_SETADDR | FPGA_TGT_MEM );
  146. FPGA_TX_BYTE( ( address >> 16 ) & 0xff );
  147. FPGA_TX_BYTE( ( address >> 8 ) & 0xff );
  148. FPGA_TX_BYTE( ( address ) & 0xff );
  149. FPGA_DESELECT();
  150. }
  151. void set_saveram_mask( uint32_t mask )
  152. {
  153. FPGA_SELECT();
  154. FPGA_TX_BYTE( FPGA_CMD_SETRAMMASK );
  155. FPGA_TX_BYTE( ( mask >> 16 ) & 0xff );
  156. FPGA_TX_BYTE( ( mask >> 8 ) & 0xff );
  157. FPGA_TX_BYTE( ( mask ) & 0xff );
  158. FPGA_DESELECT();
  159. }
  160. void set_rom_mask( uint32_t mask )
  161. {
  162. FPGA_SELECT();
  163. FPGA_TX_BYTE( FPGA_CMD_SETROMMASK );
  164. FPGA_TX_BYTE( ( mask >> 16 ) & 0xff );
  165. FPGA_TX_BYTE( ( mask >> 8 ) & 0xff );
  166. FPGA_TX_BYTE( ( mask ) & 0xff );
  167. FPGA_DESELECT();
  168. }
  169. void set_mapper( uint8_t val )
  170. {
  171. FPGA_SELECT();
  172. FPGA_TX_BYTE( FPGA_CMD_SETMAPPER( val ) );
  173. FPGA_DESELECT();
  174. }
  175. uint8_t fpga_test()
  176. {
  177. FPGA_SELECT();
  178. FPGA_TX_BYTE( FPGA_CMD_TEST );
  179. uint8_t result = FPGA_RX_BYTE();
  180. FPGA_DESELECT();
  181. return result;
  182. }
  183. uint16_t fpga_status()
  184. {
  185. FPGA_SELECT();
  186. FPGA_TX_BYTE( FPGA_CMD_GETSTATUS );
  187. uint16_t result = ( FPGA_RX_BYTE() ) << 8;
  188. result |= FPGA_RX_BYTE();
  189. FPGA_DESELECT();
  190. return result;
  191. }
  192. void fpga_set_sddma_range( uint16_t start, uint16_t end )
  193. {
  194. printf( "%s %08X -> %08X\n", __func__, start, end );
  195. FPGA_SELECT();
  196. FPGA_TX_BYTE( FPGA_CMD_SDDMA_RANGE );
  197. FPGA_TX_BYTE( start >> 8 );
  198. FPGA_TX_BYTE( start & 0xff );
  199. FPGA_TX_BYTE( end >> 8 );
  200. FPGA_TX_BYTE( end & 0xff );
  201. FPGA_DESELECT();
  202. }
  203. void fpga_sddma( uint8_t tgt, uint8_t partial )
  204. {
  205. //printf("%s %02X -> %02X\n", __func__, tgt, partial);
  206. //uint32_t test = 0;
  207. //uint8_t status = 0;
  208. BITBAND( SD_CLKREG->FIODIR, SD_CLKPIN ) = 0;
  209. FPGA_SELECT();
  210. FPGA_TX_BYTE( FPGA_CMD_SDDMA | ( tgt & 3 ) | ( partial ? FPGA_SDDMA_PARTIAL : 0 ) );
  211. FPGA_TX_BYTE( 0x00 ); /* dummy for falling DMA_EN edge */
  212. FPGA_DESELECT();
  213. FPGA_SELECT();
  214. FPGA_TX_BYTE( FPGA_CMD_GETSTATUS );
  215. DBG_SD printf( "FPGA DMA request sent, wait for completion..." );
  216. while ( FPGA_RX_BYTE() & 0x80 )
  217. {
  218. FPGA_RX_BYTE(); /* eat the 2nd status byte */
  219. }
  220. DBG_SD printf( "...complete\n" );
  221. FPGA_DESELECT();
  222. BITBAND( SD_CLKREG->FIODIR, SD_CLKPIN ) = 1;
  223. }
  224. void dac_play()
  225. {
  226. FPGA_SELECT();
  227. FPGA_TX_BYTE( FPGA_CMD_DACPLAY );
  228. FPGA_TX_BYTE( 0x00 ); /* latch reset */
  229. FPGA_DESELECT();
  230. }
  231. void dac_pause()
  232. {
  233. FPGA_SELECT();
  234. FPGA_TX_BYTE( FPGA_CMD_DACPAUSE );
  235. FPGA_TX_BYTE( 0x00 ); /* latch reset */
  236. FPGA_DESELECT();
  237. }
  238. void dac_reset()
  239. {
  240. FPGA_SELECT();
  241. FPGA_TX_BYTE( FPGA_CMD_DACRESETPTR );
  242. FPGA_TX_BYTE( 0x00 ); /* latch reset */
  243. FPGA_TX_BYTE( 0x00 ); /* latch reset */
  244. FPGA_DESELECT();
  245. }
  246. void msu_reset( uint16_t address )
  247. {
  248. FPGA_SELECT();
  249. FPGA_TX_BYTE( FPGA_CMD_MSUSETPTR );
  250. FPGA_TX_BYTE( ( address >> 8 ) & 0xff ); /* address hi */
  251. FPGA_TX_BYTE( address & 0xff ); /* address lo */
  252. FPGA_TX_BYTE( 0x00 ); /* latch reset */
  253. FPGA_TX_BYTE( 0x00 ); /* latch reset */
  254. FPGA_DESELECT();
  255. }
  256. void set_msu_status( uint8_t set, uint8_t reset )
  257. {
  258. FPGA_SELECT();
  259. FPGA_TX_BYTE( FPGA_CMD_MSUSETBITS );
  260. FPGA_TX_BYTE( set );
  261. FPGA_TX_BYTE( reset );
  262. FPGA_TX_BYTE( 0x00 ); /* latch reset */
  263. FPGA_DESELECT();
  264. }
  265. uint16_t get_msu_track()
  266. {
  267. FPGA_SELECT();
  268. FPGA_TX_BYTE( FPGA_CMD_MSUGETTRACK );
  269. uint16_t result = ( FPGA_RX_BYTE() ) << 8;
  270. result |= FPGA_RX_BYTE();
  271. FPGA_DESELECT();
  272. return result;
  273. }
  274. uint32_t get_msu_offset()
  275. {
  276. FPGA_SELECT();
  277. FPGA_TX_BYTE( FPGA_CMD_MSUGETADDR );
  278. uint32_t result = ( FPGA_RX_BYTE() ) << 24;
  279. result |= ( FPGA_RX_BYTE() ) << 16;
  280. result |= ( FPGA_RX_BYTE() ) << 8;
  281. result |= ( FPGA_RX_BYTE() );
  282. FPGA_DESELECT();
  283. return result;
  284. }
  285. uint32_t get_snes_sysclk()
  286. {
  287. FPGA_SELECT();
  288. FPGA_TX_BYTE( FPGA_CMD_GETSYSCLK );
  289. FPGA_TX_BYTE( 0x00 ); /* dummy (copy current sysclk count to register) */
  290. uint32_t result = ( FPGA_RX_BYTE() ) << 24;
  291. result |= ( FPGA_RX_BYTE() ) << 16;
  292. result |= ( FPGA_RX_BYTE() ) << 8;
  293. result |= ( FPGA_RX_BYTE() );
  294. FPGA_DESELECT();
  295. return result;
  296. }
  297. void set_bsx_regs( uint8_t set, uint8_t reset )
  298. {
  299. FPGA_SELECT();
  300. FPGA_TX_BYTE( FPGA_CMD_BSXSETBITS );
  301. FPGA_TX_BYTE( set );
  302. FPGA_TX_BYTE( reset );
  303. FPGA_TX_BYTE( 0x00 ); /* latch reset */
  304. FPGA_DESELECT();
  305. }
  306. void set_fpga_time( uint64_t time )
  307. {
  308. FPGA_SELECT();
  309. FPGA_TX_BYTE( FPGA_CMD_RTCSET );
  310. FPGA_TX_BYTE( ( time >> 48 ) & 0xff );
  311. FPGA_TX_BYTE( ( time >> 40 ) & 0xff );
  312. FPGA_TX_BYTE( ( time >> 32 ) & 0xff );
  313. FPGA_TX_BYTE( ( time >> 24 ) & 0xff );
  314. FPGA_TX_BYTE( ( time >> 16 ) & 0xff );
  315. FPGA_TX_BYTE( ( time >> 8 ) & 0xff );
  316. FPGA_TX_BYTE( time & 0xff );
  317. FPGA_TX_BYTE( 0x00 );
  318. FPGA_DESELECT();
  319. }
  320. void fpga_reset_srtc_state()
  321. {
  322. FPGA_SELECT();
  323. FPGA_TX_BYTE( FPGA_CMD_SRTCRESET );
  324. FPGA_TX_BYTE( 0x00 );
  325. FPGA_TX_BYTE( 0x00 );
  326. FPGA_DESELECT();
  327. }
  328. void fpga_reset_dspx_addr()
  329. {
  330. FPGA_SELECT();
  331. FPGA_TX_BYTE( FPGA_CMD_DSPRESETPTR );
  332. FPGA_TX_BYTE( 0x00 );
  333. FPGA_TX_BYTE( 0x00 );
  334. FPGA_DESELECT();
  335. }
  336. void fpga_write_dspx_pgm( uint32_t data )
  337. {
  338. FPGA_SELECT();
  339. FPGA_TX_BYTE( FPGA_CMD_DSPWRITEPGM );
  340. FPGA_TX_BYTE( ( data >> 16 ) & 0xff );
  341. FPGA_TX_BYTE( ( data >> 8 ) & 0xff );
  342. FPGA_TX_BYTE( ( data ) & 0xff );
  343. FPGA_TX_BYTE( 0x00 );
  344. FPGA_TX_BYTE( 0x00 );
  345. FPGA_DESELECT();
  346. }
  347. void fpga_write_dspx_dat( uint16_t data )
  348. {
  349. FPGA_SELECT();
  350. FPGA_TX_BYTE( FPGA_CMD_DSPWRITEDAT );
  351. FPGA_TX_BYTE( ( data >> 8 ) & 0xff );
  352. FPGA_TX_BYTE( ( data ) & 0xff );
  353. FPGA_TX_BYTE( 0x00 );
  354. FPGA_TX_BYTE( 0x00 );
  355. FPGA_DESELECT();
  356. }
  357. void fpga_dspx_reset( uint8_t reset )
  358. {
  359. FPGA_SELECT();
  360. FPGA_TX_BYTE( reset ? FPGA_CMD_DSPRESET : FPGA_CMD_DSPUNRESET );
  361. FPGA_TX_BYTE( 0x00 );
  362. FPGA_DESELECT();
  363. }
  364. void fpga_set_features( uint8_t feat )
  365. {
  366. printf( "set features: %02x\n", feat );
  367. FPGA_SELECT();
  368. FPGA_TX_BYTE( FPGA_CMD_SETFEATURE );
  369. FPGA_TX_BYTE( feat );
  370. FPGA_DESELECT();
  371. }
  372. void fpga_set_213f( uint8_t data )
  373. {
  374. printf( "set 213f: %d\n", data );
  375. FPGA_SELECT();
  376. FPGA_TX_BYTE( FPGA_CMD_SET213F );
  377. FPGA_TX_BYTE( data );
  378. FPGA_DESELECT();
  379. }