From e2e628d6fb8e2fe543c6ac7698ebd6223102d4bc Mon Sep 17 00:00:00 2001 From: ikari Date: Fri, 17 Dec 2010 02:58:41 +0100 Subject: [PATCH] preliminary MSU-1 audio support --- src/clock.c | 2 +- src/config.h | 3 +- src/diskio.h | 5 +- src/ff.c | 51 ++++++++++---- src/fpga_spi.c | 181 +++++++++++++++++++++++++++++++++++++++++++------ src/fpga_spi.h | 20 ++++-- src/main.c | 171 ++++++++++++++++++++++++++++++++++++++++++++-- src/memory.c | 1 + src/sdnative.c | 21 +++++- src/timer.c | 2 +- src/uart.c | 1 - 11 files changed, 404 insertions(+), 54 deletions(-) diff --git a/src/clock.c b/src/clock.c index a62deaa..f0d8ccc 100644 --- a/src/clock.c +++ b/src/clock.c @@ -27,7 +27,7 @@ void clock_init() { -> FPGA freq = 11289473.7Hz First, disable and disconnect PLL0. */ - clock_disconnect(); +// clock_disconnect(); /* PLL is disabled and disconnected. setup PCLK NOW as it cannot be changed reliably with PLL0 connected. diff --git a/src/config.h b/src/config.h index d8abba8..68320e7 100644 --- a/src/config.h +++ b/src/config.h @@ -2,6 +2,7 @@ #define _CONFIG_H // #define DEBUG_SD +// #define DEBUG_IRQ #define VER "0.0.1(NSFW)" #define IN_AHBRAM __attribute__ ((section(".ahbram"))) @@ -38,7 +39,7 @@ #define CONFIG_UART_BAUDRATE 921600 #define CONFIG_UART_DEADLOCKABLE -#define SSP_CLK_DIVISOR_FAST 4 +#define SSP_CLK_DIVISOR_FAST 2 #define SSP_CLK_DIVISOR_SLOW 250 #define SSP_CLK_DIVISOR_FPGA_FAST 6 diff --git a/src/diskio.h b/src/diskio.h index c0a6025..40a002f 100644 --- a/src/diskio.h +++ b/src/diskio.h @@ -62,7 +62,10 @@ void disk_init(void); /* Will be set to DISK_ERROR if any access on the card fails */ enum diskstates { DISK_CHANGED = 0, DISK_REMOVED, DISK_OK, DISK_ERROR }; -extern int sd_offload, ff_sd_offload, newcard; +extern int sd_offload, ff_sd_offload, sd_offload_tgt, newcard; +extern int sd_offload_partial; +extern uint16_t sd_offload_partial_start; +extern uint16_t sd_offload_partial_end; extern volatile enum diskstates disk_state; /* Disk type - part of the external API except for ATA2! */ diff --git a/src/ff.c b/src/ff.c index 6b759a0..d391644 100644 --- a/src/ff.c +++ b/src/ff.c @@ -87,7 +87,8 @@ #include "ff.h" /* FatFs configurations and declarations */ #include "diskio.h" /* Declarations of low level disk I/O functions */ - +#include "config.h" +#include "uart.h" /*-------------------------------------------------------------------------- @@ -2013,7 +2014,6 @@ FRESULT f_open ( BYTE *dir; DEF_NAMEBUF; - fp->fs = 0; /* Clear file object */ #if !_FS_READONLY @@ -2186,8 +2186,8 @@ FRESULT f_read ( if (fp->fs->wflag && fp->fs->winsect - sect < cc) mem_cpy(rbuff + ((fp->fs->winsect - sect) * SS(fp->fs)), fp->fs->win, SS(fp->fs)); #else - if ((fp->flag & FA__DIRTY) && fp->dsect - sect < cc) - mem_cpy(rbuff + ((fp->dsect - sect) * SS(fp->fs)), fp->buf, SS(fp->fs)); + if ((fp->flag & FA__DIRTY) && fp->dsect - sect < cc){ + mem_cpy(rbuff + ((fp->dsect - sect) * SS(fp->fs)), fp->buf, SS(fp->fs)); uart_putc('Y');} #endif #endif rcnt = SS(fp->fs) * cc; /* Number of bytes transferred */ @@ -2196,27 +2196,45 @@ FRESULT f_read ( #if !_FS_TINY #if !_FS_READONLY if (fp->flag & FA__DIRTY) { /* Write sector I/O buffer if needed */ +printf("DIRTY!?!\n"); if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK) ABORT(fp->fs, FR_DISK_ERR); fp->flag &= ~FA__DIRTY; } #endif if (fp->dsect != sect) { /* Fill sector buffer with file data */ - if (disk_read(fp->fs->drv, fp->buf, sect, 1) != RES_OK) - ABORT(fp->fs, FR_DISK_ERR); + if(!ff_sd_offload) { + if (disk_read(fp->fs->drv, fp->buf, sect, 1) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); + } } #endif fp->dsect = sect; } rcnt = SS(fp->fs) - (fp->fptr % SS(fp->fs)); /* Get partial sector data from sector buffer */ if (rcnt > btr) rcnt = btr; + if(!ff_sd_offload) { #if _FS_TINY - if (move_window(fp->fs, fp->dsect)) /* Move sector window */ - ABORT(fp->fs, FR_DISK_ERR); - mem_cpy(rbuff, &fp->fs->win[fp->fptr % SS(fp->fs)], rcnt); /* Pick partial sector */ + if (move_window(fp->fs, fp->dsect)) /* Move sector window */ + ABORT(fp->fs, FR_DISK_ERR); + mem_cpy(rbuff, &fp->fs->win[fp->fptr % SS(fp->fs)], rcnt); /* Pick partial sector */ #else - mem_cpy(rbuff, &fp->buf[fp->fptr % SS(fp->fs)], rcnt); /* Pick partial sector */ + mem_cpy(rbuff, &fp->buf[fp->fptr % SS(fp->fs)], rcnt); /* Pick partial sector */ +// printf("final mem_cpy, rcnt=%d, rbuff-buff=%d\n", rcnt, (void*)rbuff-buff); + } else { + sd_offload_partial_start = fp->fptr % SS(fp->fs); + sd_offload_partial_end = sd_offload_partial_start + rcnt; +// printf("partial dma. sect=%08lx start=%d end=%d\n", fp->dsect, sd_offload_partial_start, sd_offload_partial_end); + /* set start + end */ + sd_offload = 1; + sd_offload_partial = 1; + if(disk_read(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK) { + sd_offload = 0; + ABORT(fp->fs, FR_DISK_ERR); + } + sd_offload = 0; #endif + } } ff_sd_offload = 0; LEAVE_FF(fp->fs, FR_OK); @@ -2356,6 +2374,7 @@ FRESULT f_sync ( res = validate(fp->fs, fp->id); /* Check validity of the object */ if (res == FR_OK) { if (fp->flag & FA__WRITTEN) { /* Has the file been written? */ +printf("DIRTY?!?!?!\n"); #if !_FS_TINY /* Write-back dirty buffer */ if (fp->flag & FA__DIRTY) { if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK) @@ -2696,8 +2715,14 @@ FRESULT f_lseek ( fp->flag &= ~FA__DIRTY; } #endif - if (disk_read(fp->fs->drv, fp->buf, nsect, 1) != RES_OK) - ABORT(fp->fs, FR_DISK_ERR); + if(!ff_sd_offload) { + sd_offload_partial=0; + if (disk_read(fp->fs->drv, fp->buf, nsect, 1) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); + } else { + sd_offload_partial=1; + sd_offload_partial_start = fp->fptr % SS(fp->fs); + } #endif fp->dsect = nsect; } @@ -2708,7 +2733,7 @@ FRESULT f_lseek ( } #endif } - + ff_sd_offload = 0; LEAVE_FF(fp->fs, res); } diff --git a/src/fpga_spi.c b/src/fpga_spi.c index 093a04b..7b394aa 100644 --- a/src/fpga_spi.c +++ b/src/fpga_spi.c @@ -29,20 +29,50 @@ cmd param function ============================================= - 00 bbhhll set address to 0xbbhhll - 01 bbhhll set SNES input address mask to 0xbbhhll - 02 bbhhll set SRAM address mask to 0xbbhhll + 0t bbhhll set address to 0xbbhhll + t = target + target: 0 = RAM + 1 = MSU Audio buffer + 2 = MSU Data buffer + targets 1 & 2 only require 2 address bytes to + be written. + + 10 bbhhll set SNES input address mask to 0xbbhhll + 20 bbhhll set SRAM address mask to 0xbbhhll + 3m - set mapper to m 0=HiROM, 1=LoROM, 2=ExHiROM, 6=SF96, 7=Menu - 40 - trigger SD DMA (512b from SD to memory) - 80 - read with increment - 81 - read w/o increment - 90 {xx}* write xx with increment - 91 {xx}* write xx w/o increment - Eu - set memory unit (u=0: "ROM"; u=1: SRAM) + + 4s - trigger SD DMA (512b from SD to memory) + s: Bit 2 = partial, Bit 1:0 = target + target: see above + + 60 sssseeee set SD DMA partial transfer start+end + ssss = start offset (msb first) + eeee = end offset (msb first) + + 80 - read with increment (RAM only) + 81 - read w/o increment (RAM only) + + 90 {xx}* write xx with increment (RAM only) + 91 {xx}* write xx w/o increment (RAM only) + + E0 ssrr set MSU-1 status register (=FPGA status byte 2) + ss = bits to set in status register (1=set) + rr = bits to reset in status register (1=reset) + + E1 - pause DAC + E2 - resume/play DAC + E3 - reset DAC playback pointer (0) + F0 - receive test token (to see if FPGA is alive) F1 - receive status - + + F2 - get MSU data address (32bit, MSB first) + F3 - get MSU audio track no. (16bit, MSB first) + F4 - get MSU volume (8bit) + + FF {xx]* echo (returns the sent data in the next byte) */ #include @@ -58,6 +88,22 @@ void fpga_spi_init(void) { spi_init(SPI_SPEED_FPGA_FAST); } +void set_msu_addr(uint32_t address) { + FPGA_SELECT(); + FPGA_TX_BYTE(0x02); + FPGA_TX_BYTE((address>>8)&0xff); + FPGA_TX_BYTE((address)&0xff); + FPGA_DESELECT(); +} + +void set_dac_addr(uint32_t address) { + FPGA_SELECT(); + FPGA_TX_BYTE(0x01); + FPGA_TX_BYTE((address>>8)&0xff); + FPGA_TX_BYTE((address)&0xff); + FPGA_DESELECT(); +} + void set_mcu_addr(uint32_t address) { FPGA_SELECT(); FPGA_TX_BYTE(0x00); @@ -69,7 +115,7 @@ void set_mcu_addr(uint32_t address) { void set_saveram_mask(uint32_t mask) { FPGA_SELECT(); - FPGA_TX_BYTE(0x02); + FPGA_TX_BYTE(0x20); FPGA_TX_BYTE((mask>>16)&0xff); FPGA_TX_BYTE((mask>>8)&0xff); FPGA_TX_BYTE((mask)&0xff); @@ -78,7 +124,7 @@ void set_saveram_mask(uint32_t mask) { void set_rom_mask(uint32_t mask) { FPGA_SELECT(); - FPGA_TX_BYTE(0x01); + FPGA_TX_BYTE(0x10); FPGA_TX_BYTE((mask>>16)&0xff); FPGA_TX_BYTE((mask>>8)&0xff); FPGA_TX_BYTE((mask)&0xff); @@ -100,25 +146,116 @@ uint8_t fpga_test() { return result; } -uint8_t fpga_status() { +uint16_t fpga_status() { FPGA_SELECT(); FPGA_TX_BYTE(0xF1); /* STATUS */ FPGA_TX_BYTE(0x00); /* dummy */ + uint16_t result = (FPGA_RX_BYTE()) << 8; + result |= FPGA_RX_BYTE(); + FPGA_DESELECT(); + return result; +} + +void fpga_set_sddma_range(uint16_t start, uint16_t end) { + FPGA_SELECT(); + FPGA_TX_BYTE(0x60); /* DMA_RANGE */ + FPGA_TX_BYTE(start>>8); + FPGA_TX_BYTE(start&0xff); + FPGA_TX_BYTE(end>>8); + FPGA_TX_BYTE(end&0xff); +//if(tgt==1 && (test=FPGA_RX_BYTE()) != 0x41) printf("!!!!!!!!!!!!!!! -%02x- \n", test); + FPGA_DESELECT(); +} + +void fpga_sddma(uint8_t tgt, uint8_t partial) { + uint32_t test = 0; + uint8_t status = 0; + BITBAND(SD_CLKREG->FIODIR, SD_CLKPIN) = 0; + FPGA_SELECT(); + FPGA_TX_BYTE(0x40 | (tgt & 0x3) | ((partial & 1) << 2) ); /* DO DMA */ + FPGA_TX_BYTE(0x00); /* dummy for falling DMA_EN edge */ +//if(tgt==1 && (test=FPGA_RX_BYTE()) != 0x41) printf("!!!!!!!!!!!!!!! -%02x- \n", test); + FPGA_DESELECT(); + FPGA_SELECT(); + FPGA_TX_BYTE(0xF1); /* STATUS */ + FPGA_TX_BYTE(0x00); /* dummy */ + while((status=FPGA_RX_BYTE()) & 0x80) { + FPGA_RX_BYTE(); /* eat the 2nd status byte */ + test++; + } + FPGA_DESELECT(); + if(test<10)printf("loopy: %ld %02x\n", test, status); + BITBAND(SD_CLKREG->FIODIR, SD_CLKPIN) = 1; +} + +void set_dac_vol(uint8_t volume) { + FPGA_SELECT(); + FPGA_TX_BYTE(0x50); + FPGA_TX_BYTE(volume); + FPGA_TX_BYTE(0x00); /* latch rise */ + FPGA_TX_BYTE(0x00); /* latch fall */ + FPGA_DESELECT(); +} + +void dac_play() { + FPGA_SELECT(); + FPGA_TX_BYTE(0xe2); + FPGA_TX_BYTE(0x00); /* latch reset */ + FPGA_DESELECT(); +} + +void dac_pause() { + FPGA_SELECT(); + FPGA_TX_BYTE(0xe1); + FPGA_TX_BYTE(0x00); /* latch reset */ + FPGA_DESELECT(); +} + +void dac_reset() { + FPGA_SELECT(); + FPGA_TX_BYTE(0xe3); + FPGA_TX_BYTE(0x00); /* latch reset */ + FPGA_DESELECT(); +} + +void set_msu_status(uint8_t set, uint8_t reset) { + FPGA_SELECT(); + FPGA_TX_BYTE(0xe0); + FPGA_TX_BYTE(set); + FPGA_TX_BYTE(reset); + FPGA_TX_BYTE(0x00); /* latch reset */ + FPGA_TX_BYTE(0x00); /* latch reset */ + FPGA_DESELECT(); +} + +uint8_t get_msu_volume() { + FPGA_SELECT(); + FPGA_TX_BYTE(0xF4); /* MSU_VOLUME */ + FPGA_TX_BYTE(0x00); /* dummy */ uint8_t result = FPGA_RX_BYTE(); FPGA_DESELECT(); return result; } -void fpga_sd2ram() { - BITBAND(SD_CLKREG->FIODIR, SD_CLKPIN) = 0; +uint16_t get_msu_track() { FPGA_SELECT(); - FPGA_TX_BYTE(0x40); /* DO DMA */ - FPGA_TX_BYTE(0x00); /* dummy for falling DMA_EN edge */ - FPGA_DESELECT(); - FPGA_SELECT(); - FPGA_TX_BYTE(0xF1); /* STATUS */ + FPGA_TX_BYTE(0xF3); /* MSU_TRACK */ FPGA_TX_BYTE(0x00); /* dummy */ - while(FPGA_RX_BYTE() & 0x80); + uint16_t result = (FPGA_RX_BYTE()) << 8; + result |= FPGA_RX_BYTE(); FPGA_DESELECT(); - BITBAND(SD_CLKREG->FIODIR, SD_CLKPIN) = 1; + return result; } + +uint32_t get_msu_offset() { + FPGA_SELECT(); + FPGA_TX_BYTE(0xF2); /* MSU_OFFSET */ + FPGA_TX_BYTE(0x00); /* dummy */ + uint32_t result = (FPGA_RX_BYTE()) << 24; + result |= (FPGA_RX_BYTE()) << 16; + result |= (FPGA_RX_BYTE()) << 8; + result |= (FPGA_RX_BYTE()); + FPGA_DESELECT(); + return result; +} + diff --git a/src/fpga_spi.h b/src/fpga_spi.h index 83bf5a7..a651add 100644 --- a/src/fpga_spi.h +++ b/src/fpga_spi.h @@ -1,6 +1,6 @@ /* sd2snes - SD card based universal cartridge for the SNES Copyright (C) 2009-2010 Maximilian Rehkopf - AVR firmware portion + uC firmware portion Inspired by and based on code from sd2iec, written by Ingo Korb et al. See sdcard.c|h, config.h. @@ -34,7 +34,9 @@ #define FPGA_SS_REG LPC_GPIO0 #define FPGA_SELECT() do {FPGA_TX_SYNC(); BITBAND(FPGA_SS_REG->FIOCLR, FPGA_SS_BIT) = 1;} while (0) +#define FPGA_SELECT_ASYNC() do {BITBAND(FPGA_SS_REG->FIOCLR, FPGA_SS_BIT) = 1;} while (0) #define FPGA_DESELECT() do {FPGA_TX_SYNC(); BITBAND(FPGA_SS_REG->FIOSET, FPGA_SS_BIT) = 1;} while (0) +#define FPGA_DESELECT_ASYNC() do {BITBAND(FPGA_SS_REG->FIOSET, FPGA_SS_BIT) = 1;} while (0) #define FPGA_TX_SYNC() spi_tx_sync() #define FPGA_TX_BYTE(x) spi_tx_byte(x) @@ -48,14 +50,24 @@ void fpga_spi_init(void); uint8_t fpga_test(void); -uint8_t fpga_status(void); +uint16_t fpga_status(void); void spi_fpga(void); void spi_sd(void); void spi_none(void); void set_mcu_addr(uint32_t); +void set_dac_addr(uint32_t); +void set_dac_vol(uint8_t); +void dac_play(void); +void dac_pause(void); +void dac_reset(void); +void set_msu_addr(uint32_t); +void set_msu_status(uint8_t set, uint8_t reset); void set_saveram_mask(uint32_t); void set_rom_mask(uint32_t); void set_mapper(uint8_t val); -void fpga_sd2ram(void); - +void fpga_sddma(uint8_t tgt, uint8_t partial); +void fpga_set_sddma_range(uint16_t start, uint16_t end); +uint8_t get_msu_volume(void); +uint16_t get_msu_track(void); +uint32_t get_msu_offset(void); #endif diff --git a/src/main.c b/src/main.c index 4bb9c07..f9b1077 100644 --- a/src/main.c +++ b/src/main.c @@ -30,7 +30,11 @@ int i; -int sd_offload = 0, ff_sd_offload = 0; +int sd_offload = 0, ff_sd_offload = 0, sd_offload_tgt = 0; +int sd_offload_partial = 0; +uint16_t sd_offload_partial_start = 0; +uint16_t sd_offload_partial_end = 0; + /* FIXME HACK */ volatile enum diskstates disk_state; extern volatile tick_t ticks; @@ -44,9 +48,8 @@ int main(void) { /* connect UART3 on P0[25:26] + SSP0 on P0[15:18] SSP1 on P0[6:9] + MAT3.0 on P0[10] */ LPC_PINCON->PINSEL1 = BV(18) | BV(19) | BV(20) | BV(21) /* UART3 */ | BV(3) | BV(5); /* SSP0 (FPGA) except SS */ - LPC_PINCON->PINSEL0 = BV(31) /* SSP0 */ + LPC_PINCON->PINSEL0 = BV(31); /* SSP0 */ /* | BV(13) | BV(15) | BV(17) | BV(19) SSP1 (SD) */ - | BV(20) | BV(21); /* MAT3.0 (FPGA clock) */ /* pull-down CIC data lines */ LPC_PINCON->PINMODE3 = BV(18) | BV(19) | BV(20) | BV(21); @@ -62,6 +65,7 @@ int main(void) { led_init(); /* do this last because the peripheral init()s change PCLK dividers */ clock_init(); + LPC_PINCON->PINSEL0 |= BV(20) | BV(21); /* MAT3.0 (FPGA clock) */ led_pwm(); sdn_init(); fpga_spi_init(); @@ -76,7 +80,6 @@ led_pwm(); LPC_TIM3->MR0=1; LPC_TIM3->TCR=1; fpga_init(); -// fpga_pgm((uint8_t*)"/main.bit.rle"); fpga_rompgm(); restart: if(disk_state == DISK_CHANGED) { @@ -121,7 +124,7 @@ restart: snes_bootprint(" Loading ... \0"); if(get_cic_state() == CIC_PAIR) { printf("PAIR MODE ENGAGED!\n"); - cic_pair(CIC_PAL, CIC_PAL); + cic_pair(CIC_NTSC, CIC_NTSC); } rdyled(1); readled(0); @@ -176,6 +179,7 @@ restart: load_sram((uint8_t*)"/sd2snes/sd2snes.dir", SRAM_DIR_ADDR); } /* load menu */ + fpga_pgm((uint8_t*)"/main.bit.rle"); uart_putc('('); load_rom((uint8_t*)"/sd2snes/menu.bin", SRAM_MENU_ADDR); /* force memory size + mapper */ @@ -222,7 +226,7 @@ restart: } set_mcu_ovr(0); snes_reset(1); - delay_ms(1); + delay_ms(10); snes_reset(0); break; case SNES_CMD_SETRTC: @@ -234,8 +238,161 @@ restart: break; } } - printf("cmd was %x, going to snes main loop\n", cmd); + +/* MSU1 STUFF, GET ME OUTTA HERE */ + FIL durr; + f_open(&durr, "/SF96SOE.smc", FA_READ); + ff_sd_offload=1; + sd_offload_tgt=2; + f_lseek(&durr, 79L); + set_msu_addr(0); + UINT bytes_read = 1024; + UINT bytes_read2 = 1; + uint16_t volume=0; + set_dac_vol(0x00); + spi_set_speed(SSP_CLK_DIVISOR_FAST); + while(fpga_status() & 0x4000); + uint16_t fpga_status_prev = fpga_status(); + uint16_t fpga_status_now = fpga_status(); + uint16_t dac_addr = 0; + uint16_t msu_addr = 0; + uint8_t msu_repeat = 0; + uint16_t msu_track = 0; + uint32_t msu_offset = 0; + uint8_t msu_volume = 0; + uint8_t msu_volupdate = 0; + uint8_t msu_volupdate_cnt = 0; + set_dac_addr(dac_addr); + dac_pause(); + dac_reset(); +/* audio_start, data_start, volume_start, audio_ctrl[1:0], ctrl_start */ +while(1){ + fpga_status_now = fpga_status(); + if(fpga_status_now & 0x0020) { + char suffix[11]; + + /* get trackno */ + msu_track = get_msu_track(); + printf("Audio requested! Track=%d\n", msu_track); + + /* open file */ + f_close(&file_handle); + snprintf(suffix, sizeof(suffix), "-%d.wav", msu_track); + strcpy((char*)file_buf, (char*)file_lfn); + strcpy(strrchr((char*)file_buf, (int)'.'), suffix); + f_open(&file_handle, (const TCHAR*)file_buf, FA_READ); + ff_sd_offload=1; + sd_offload_tgt=1; + f_lseek(&file_handle, 44L); + ff_sd_offload=1; + sd_offload_tgt=1; + set_dac_addr(0); + dac_pause(); + dac_reset(); + f_read(&file_handle, file_buf, 2048, &bytes_read); + + /* clear busy bit */ + set_msu_status(0x00, 0x20); /* set no bits, reset bit 5 */ + } + + if(fpga_status_now & 0x0010) { + msu_offset=get_msu_offset(); + printf("Data requested! Offset=%08lx\n", msu_offset); +// get address +// open file + fill buffer +// clear busy bit + set_msu_status(0x00, 0x10); + } + + if(fpga_status_now & 0x0001) { + if(fpga_status_now & 0x0004) { + msu_repeat = 1; + set_msu_status(0x04, 0x01); /* set bit 2, reset bit 0 */ + printf("Repeat set!\n"); + } else { + msu_repeat = 0; + set_msu_status(0x00, 0x05); /* set no bits, reset bit 0+2 */ + printf("Repeat clear!\n"); + } + + if(fpga_status_now & 0x0002) { + printf("PLAY!\n"); + set_msu_status(0x02, 0x01); /* set bit 0, reset bit 1 */ + dac_play(); + } else { + printf("PAUSE!\n"); + set_msu_status(0x00, 0x03); /* set no bits, reset bit 1+0 */ + dac_pause(); + } + } + + /* Audio buffer refill */ + if((fpga_status_now & 0x4000) != (fpga_status_prev & 0x4000)) { + if(fpga_status_now & 0x4000) { + dac_addr = 0x0; + } else { + dac_addr = 0x400; + } + set_dac_addr(dac_addr); + sd_offload_tgt=1; + ff_sd_offload=1; + f_read(&file_handle, file_buf, 1024, &bytes_read); + } + + /* volume update */ + if(msu_volupdate && !(msu_volupdate_cnt++ & 0x1)) { + if(volume < msu_volume) { + volume++; + } else if(volume > msu_volume) { + volume--; + } else { + msu_volupdate = 0; + } + printf("should not see me!\n"); + set_dac_vol(volume); + } + + /* Data buffer refill */ + if((fpga_status_now & 0x2000) != (fpga_status_prev & 0x2000)) { + printf("data\n"); + if(fpga_status_now & 0x2000) { + msu_addr = 0x0; + } else { + msu_addr = 0x2000; + } + set_msu_addr(msu_addr); + sd_offload_tgt=2; + ff_sd_offload=1; + f_read(&durr, file_buf, 8192, &bytes_read2); + } + fpga_status_prev = fpga_status_now; + + /* handle loop / end */ + if(bytes_read<1024) { + ff_sd_offload=0; + sd_offload=0; + if(msu_repeat) { + printf("loop\n"); + ff_sd_offload=1; + sd_offload_tgt=1; + f_lseek(&file_handle, 44L); + ff_sd_offload=1; + sd_offload_tgt=1; + f_read(&file_handle, file_buf, 1024 - bytes_read, &bytes_read); + } else { + set_msu_status(0x00, 0x02); /* clear play bit */ + } + bytes_read=1024; + } + if(!bytes_read2) { + f_lseek(&durr, 0L); + uart_putc('*'); + } +} + +/* END OF MSU1 STUFF */ + cmd=0; uint8_t snes_reset_prev=0, snes_reset_now=0, snes_reset_state=0; uint16_t reset_count=0; diff --git a/src/memory.c b/src/memory.c index 51e796b..be2adc6 100644 --- a/src/memory.c +++ b/src/memory.c @@ -186,6 +186,7 @@ printf("%s\n", filename); // FPGA_TX_BYTE(0x91); /* write w/ increment */ for(;;) { ff_sd_offload=1; + sd_offload_tgt=0; tickstmp=getticks(); bytes_read = file_read(); ticks_read+=getticks()-tickstmp; diff --git a/src/sdnative.c b/src/sdnative.c index 92bcf60..a7a1fd6 100644 --- a/src/sdnative.c +++ b/src/sdnative.c @@ -348,7 +348,7 @@ int send_command_fast(uint8_t* cmd, uint8_t* rsp, uint8_t* buf){ do { if(dat) { if(!(BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN))) { - DBG_SD printf("data start during response\n"); + printf("data start during response\n"); j=datcnt; state=CMD_RSPDAT; break; @@ -401,6 +401,7 @@ int send_command_fast(uint8_t* cmd, uint8_t* rsp, uint8_t* buf){ } if(dat && state != CMD_DAT) { /* response ended before data */ + BITBAND(SD_CMDREG->FIODIR, SD_CMDPIN) = 1; state=CMD_DAT; j=datcnt; datshift=8; @@ -410,7 +411,13 @@ int send_command_fast(uint8_t* cmd, uint8_t* rsp, uint8_t* buf){ } wiggle_fast_neg1(); /* eat the start bit */ if(sd_offload) { - fpga_sd2ram(); + if(sd_offload_partial) { + fpga_set_sddma_range(sd_offload_partial_start, sd_offload_partial_end); + fpga_sddma(sd_offload_tgt, 1); + sd_offload_partial=0; + } else { + fpga_sddma(sd_offload_tgt, 0); + } state=CMD_RSP; return rsplen; } @@ -460,6 +467,7 @@ int send_command_fast(uint8_t* cmd, uint8_t* rsp, uint8_t* buf){ } rsp-=rsplen; DBG_SD printf("send_command_fast: CMD%d response: %02x%02x%02x%02x%02x%02x\n", cmdno, rsp[0], rsp[1], rsp[2], rsp[3], rsp[4], rsp[5]); + BITBAND(SD_CMDREG->FIODIR, SD_CMDPIN) = 1; return rsplen; } @@ -528,7 +536,13 @@ void stream_datablock(uint8_t *buf) { } wiggle_fast_neg1(); /* eat the start bit */ if(sd_offload) { - fpga_sd2ram(); + if(sd_offload_partial) { + fpga_set_sddma_range(sd_offload_partial_start, sd_offload_partial_end); + fpga_sddma(sd_offload_tgt, 1); + sd_offload_partial=0; + } else { + fpga_sddma(sd_offload_tgt, 0); + } } else { while(1) { datdata = SD_DAT << 4; @@ -677,6 +691,7 @@ void read_block(uint32_t address, uint8_t *buf) { last_block=address; } else { if(during_blocktrans) { +// uart_putc('_'); //printf("nonseq read (%lx -> %lx), restarting transmission\n", last_block, address); /* send STOP_TRANSMISSION to end an open READ/WRITE_MULTIPLE_BLOCK */ cmd_fast(STOP_TRANSMISSION, 0, 0x61, NULL, rsp); diff --git a/src/timer.c b/src/timer.c index b2f1665..d6ab8ae 100644 --- a/src/timer.c +++ b/src/timer.c @@ -47,7 +47,7 @@ void timer_init(void) { BITBAND(LPC_SC->PCLKSEL1, 26) = 1; BITBAND(LPC_SC->PCLKSEL1, PCLK_TIMER3) = 1; /* enable SysTick */ - SysTick_Config(SysTick->CALIB & SysTick_CALIB_TENMS_Msk); + SysTick_Config((SysTick->CALIB & SysTick_CALIB_TENMS_Msk)); } void delay_us(unsigned int time) { diff --git a/src/uart.c b/src/uart.c index b5697f7..9eb1f6a 100644 --- a/src/uart.c +++ b/src/uart.c @@ -111,7 +111,6 @@ static volatile unsigned int read_idx,write_idx; void UART_HANDLER(void) { int iir = UART_REGS->IIR; - if (!(iir & 1)) { /* Interrupt is pending */ switch (iir & 14) {