preliminary MSU-1 audio support

This commit is contained in:
ikari 2010-12-17 02:58:41 +01:00
parent 6c27daa30b
commit e2e628d6fb
11 changed files with 404 additions and 54 deletions

View File

@ -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.

View File

@ -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

View File

@ -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! */

View File

@ -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);
}

View File

@ -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 <arm/NXP/LPC17xx/LPC17xx.h>
@ -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;
}

View File

@ -1,6 +1,6 @@
/* sd2snes - SD card based universal cartridge for the SNES
Copyright (C) 2009-2010 Maximilian Rehkopf <otakon@gmx.net>
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

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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) {

View File

@ -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) {