SPI offloading -> 5x loading speed (needs code cleanup)
This commit is contained in:
@@ -80,6 +80,8 @@ DRESULT disk_getinfo(BYTE drv, BYTE page, void *buffer);
|
||||
|
||||
void disk_init(void);
|
||||
|
||||
uint8_t SD_SPI_OFFLOAD;
|
||||
|
||||
/* Will be set to DISK_ERROR if any access on the card fails */
|
||||
enum diskstates { DISK_CHANGED = 0, DISK_REMOVED, DISK_OK, DISK_ERROR };
|
||||
|
||||
|
||||
8
src/ff.c
8
src/ff.c
@@ -60,6 +60,7 @@
|
||||
#include "ff.h" /* FatFs declarations */
|
||||
#include "diskio.h" /* Include file for user provided disk functions */
|
||||
#include "uart.h"
|
||||
#include "fpga.h"
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
@@ -1603,8 +1604,12 @@ FRESULT f_read (
|
||||
cc = btr / SS(fs); /* When left bytes >= SS(fs), */
|
||||
if (cc) { /* Read maximum contiguous sectors directly */
|
||||
if (cc > fp->csect) cc = fp->csect;
|
||||
if(SPI_OFFLOAD) {
|
||||
SD_SPI_OFFLOAD = 1;
|
||||
}
|
||||
if (disk_read(fs->drive, rbuff, sect, (BYTE)cc) != RES_OK)
|
||||
goto fr_error;
|
||||
SD_SPI_OFFLOAD = 0;
|
||||
fp->csect -= (BYTE)(cc - 1);
|
||||
fp->curr_sect += cc - 1;
|
||||
rcnt = cc * SS(fs);
|
||||
@@ -1619,10 +1624,13 @@ FRESULT f_read (
|
||||
}
|
||||
}
|
||||
|
||||
SPI_OFFLOAD = 0;
|
||||
return FR_OK;
|
||||
|
||||
fr_error: /* Abort this file due to an unrecoverable error */
|
||||
fp->flag |= FA__ERROR;
|
||||
SPI_OFFLOAD = 0;
|
||||
SD_SPI_OFFLOAD = 0;
|
||||
return FR_RW_ERROR;
|
||||
}
|
||||
|
||||
|
||||
@@ -55,6 +55,10 @@ void fpga_init() {
|
||||
DDRD |= _BV(PD3) | _BV(PD4); // PD3, PD4 are outputs
|
||||
|
||||
DDRA = ~_BV(PA3); // PA3 is input <- DONE
|
||||
|
||||
DDRB |= _BV(PB2); // DMA_CTRL preinit
|
||||
PORTB |= _BV(PB2);
|
||||
SPI_OFFLOAD=0;
|
||||
set_cclk(0); // initial clk=0
|
||||
}
|
||||
|
||||
@@ -64,7 +68,7 @@ int fpga_get_done(void) {
|
||||
|
||||
void fpga_postinit() {
|
||||
DDRA |= _BV(PA0) | _BV(PA1) | _BV(PA2) | _BV(PA4) | _BV(PA5) | _BV(PA6); // MAPPER+NEXTADDR output
|
||||
DDRB |= _BV(PB2) | _BV(PB1) | _BV(PB0); // turn PB2 into output, enable AVR_BANK
|
||||
DDRB |= _BV(PB1) | _BV(PB0); // turn PB2 into output, enable AVR_BANK
|
||||
DDRD |= _BV(PD7); // turn PD7 into output
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ void set_avr_addr_en(uint8_t val);
|
||||
void set_avr_mapper(uint8_t val);
|
||||
void set_avr_bank(uint8_t val);
|
||||
|
||||
uint8_t SPI_OFFLOAD;
|
||||
|
||||
#define FPGA_TEST_TOKEN (0xa5)
|
||||
|
||||
|
||||
51
src/main.c
51
src/main.c
@@ -48,6 +48,7 @@
|
||||
#include "spi.h"
|
||||
#include "avrcompat.h"
|
||||
#include "filetypes.h"
|
||||
#include "sdcard.h"
|
||||
|
||||
void writetest(void) {
|
||||
// HERE BE LIONS, GET IN THE CAR
|
||||
@@ -116,12 +117,6 @@ void poison_memory(void) {
|
||||
}
|
||||
#endif
|
||||
|
||||
void avr_goto_addr(const uint32_t val) {
|
||||
AVR_ADDR_RESET();
|
||||
for(uint32_t i=0; i<val; i++) {
|
||||
AVR_NEXTADDR();
|
||||
}
|
||||
}
|
||||
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 1)
|
||||
int main(void) __attribute__((OS_main));
|
||||
#endif
|
||||
@@ -189,7 +184,41 @@ restart:
|
||||
uint16_t mem_dir_id = sram_readshort(SRAM_DIRID);
|
||||
uint32_t mem_magic = sram_readlong(SRAM_SCRATCHPAD);
|
||||
|
||||
|
||||
while(0) {
|
||||
SD_SPI_OFFLOAD=1;
|
||||
sd_read(0, file_buf, 32L, 1);
|
||||
// sram_writeblock((void*)file_buf, 0, 0x200);
|
||||
sram_hexdump(0,0x10);
|
||||
uart_putc('+');
|
||||
}
|
||||
/* here be strange monsters */
|
||||
while(0){
|
||||
// uint16_t hurdur1 = 0, hurdur2 = 0;
|
||||
spiTransferByte(0x00);
|
||||
spiTransferByte(0x00);
|
||||
spiTransferByte(0x00);
|
||||
spiTransferByte(0x00);
|
||||
spiTransferByte(0x00);
|
||||
spiTransferByte(0x00);
|
||||
spiTransferByte(0x00);
|
||||
spiTransferByte(0x00);
|
||||
spiTransferByte(0x00);
|
||||
spiTransferByte(0x00);
|
||||
spiTransferByte(0x00);
|
||||
spiTransferByte(0x00);
|
||||
spiTransferByte(0x00);
|
||||
PORTB |= _BV(PB2);
|
||||
DDRB |= _BV(PB2);
|
||||
PORTB &= ~_BV(PB2);
|
||||
DDRB &= ~_BV(PB7); // tristate SCK
|
||||
PORTB |= _BV(PB2);
|
||||
DDRB &= ~_BV(PB2);
|
||||
while(!(PINB & _BV(PB2))) {
|
||||
}
|
||||
DDRB |= _BV(PB7);
|
||||
_delay_ms(1);
|
||||
// dprintf("hurdur1=%d hurdur2=%d\n", hurdur1, hurdur2);
|
||||
}
|
||||
if((mem_magic != 0x12345678) || (mem_dir_id != saved_dir_id)) {
|
||||
uint16_t curr_dir_id = scan_dir(fs_path, 0, 0); // generate files footprint
|
||||
dprintf("curr dir id = %x\n", curr_dir_id);
|
||||
@@ -207,7 +236,7 @@ restart:
|
||||
save_sram((uint8_t*)"/sd2snes/sd2snes.db", endaddr-SRAM_DB_ADDR, SRAM_DB_ADDR);
|
||||
save_sram((uint8_t*)"/sd2snes/sd2snes.dir", direndaddr-(SRAM_DIR_ADDR), SRAM_DIR_ADDR);
|
||||
dprintf("done\n");
|
||||
sram_hexdump(SRAM_DB_ADDR, 0x400);
|
||||
// sram_hexdump(SRAM_DB_ADDR, 0x400);
|
||||
} else {
|
||||
dprintf("saved dir id = %x\n", saved_dir_id);
|
||||
dprintf("different card, consistent db, loading db...\n");
|
||||
@@ -229,10 +258,14 @@ restart:
|
||||
|
||||
led_pwm();
|
||||
|
||||
// sram_hexdump(0, 0x200);
|
||||
uart_putc('(');
|
||||
load_rom((uint8_t*)"/sd2snes/menu.bin");
|
||||
set_rom_mask(0x3fffff); // force mirroring off
|
||||
uart_putc(')');
|
||||
uart_putcrlf();
|
||||
// sram_hexdump(0, 0x200);
|
||||
// save_sram((uint8_t*)"/sd2snes/dump", 65536, 0);
|
||||
|
||||
sram_writebyte(0, SRAM_CMD_ADDR);
|
||||
|
||||
@@ -256,6 +289,7 @@ restart:
|
||||
set_avr_ena(0);
|
||||
dprintf("Selected name: %s\n", file_lfn);
|
||||
load_rom(file_lfn);
|
||||
// save_sram((uint8_t*)"/sd2snes/test.smc", romprops.romsize_bytes, 0);
|
||||
if(romprops.ramsize_bytes) {
|
||||
strcpy(strrchr((char*)file_lfn, (int)'.'), ".srm");
|
||||
dprintf("SRM file: %s\n", file_lfn);
|
||||
@@ -281,7 +315,6 @@ restart:
|
||||
uint8_t snes_reset_prev=0, snes_reset_now=0, snes_reset_state=0;
|
||||
uint16_t reset_count=0;
|
||||
while(fpga_test() == FPGA_TEST_TOKEN) {
|
||||
dprintf("%02X\n", fpga_test());
|
||||
snes_reset_now=get_snes_reset();
|
||||
if(snes_reset_now) {
|
||||
if(!snes_reset_prev) {
|
||||
|
||||
15
src/memory.c
15
src/memory.c
@@ -124,7 +124,7 @@ void sram_writeblock(void* buf, uint32_t addr, uint16_t size) {
|
||||
}
|
||||
|
||||
uint32_t load_rom(uint8_t* filename) {
|
||||
uint8_t dummy;
|
||||
// uint8_t dummy;
|
||||
set_avr_bank(0);
|
||||
UINT bytes_read;
|
||||
DWORD filesize;
|
||||
@@ -132,18 +132,25 @@ uint32_t load_rom(uint8_t* filename) {
|
||||
file_open(filename, FA_READ);
|
||||
filesize = file_handle.fsize;
|
||||
smc_id(&romprops);
|
||||
dprintf("no nervous breakdown beyond this point! or else!\n");
|
||||
if(file_res) {
|
||||
uart_putc('?');
|
||||
uart_putc(0x30+file_res);
|
||||
return 0;
|
||||
}
|
||||
f_lseek(&file_handle, romprops.offset);
|
||||
spi_none();
|
||||
for(;;) {
|
||||
SPI_OFFLOAD=1;
|
||||
spi_none();
|
||||
bytes_read = file_read();
|
||||
spi_none();
|
||||
if (file_res || !bytes_read) break;
|
||||
spi_fpga();
|
||||
if(!(count++ % 8)) {
|
||||
// toggle_busy_led();
|
||||
bounce_busy_led();
|
||||
uart_putc('.');
|
||||
}
|
||||
/* spi_fpga();
|
||||
spiTransferByte(0x91); // write w/ increment
|
||||
if(!(count++ % 8)) {
|
||||
// toggle_busy_led();
|
||||
@@ -156,7 +163,7 @@ uint32_t load_rom(uint8_t* filename) {
|
||||
loop_until_bit_is_set(SPSR, SPIF);
|
||||
dummy = SPDR;
|
||||
}
|
||||
spiTransferByte(0x00); // dummy tx for increment+write pulse
|
||||
spiTransferByte(0x00); // dummy tx for increment+write pulse */
|
||||
}
|
||||
file_close();
|
||||
spi_none();
|
||||
|
||||
48
src/sdcard.c
48
src/sdcard.c
@@ -60,6 +60,7 @@
|
||||
#include <avr/interrupt.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#include <util/crc16.h>
|
||||
#include <util/delay.h>
|
||||
#include "config.h"
|
||||
#include "avrcompat.h"
|
||||
#include "crc7.h"
|
||||
@@ -308,6 +309,8 @@ static void sdInit(const uint8_t card) {
|
||||
uint8_t i;
|
||||
uint16_t counter;
|
||||
|
||||
SD_SPI_OFFLOAD = 0;
|
||||
|
||||
counter = 0xffff;
|
||||
do {
|
||||
// Prepare for ACMD, send CMD55: APP_CMD
|
||||
@@ -557,24 +560,46 @@ DRESULT sd_read(BYTE drv, BYTE *buffer, DWORD sector, BYTE count) {
|
||||
|
||||
// Get data
|
||||
crc = 0;
|
||||
// Initiate data exchange over SPI
|
||||
SPDR = 0xff;
|
||||
|
||||
for (i=0; i<512; i++) {
|
||||
// Wait until data has been received
|
||||
loop_until_bit_is_set(SPSR, SPIF);
|
||||
tmp = SPDR;
|
||||
// Transmit the next byte while we store the current one
|
||||
if(SD_SPI_OFFLOAD) {
|
||||
// uart_putc('O');
|
||||
PORTB |= _BV(PB2);
|
||||
DDRB |= _BV(PB2);
|
||||
PORTB &= ~_BV(PB2);
|
||||
PORTB |= _BV(PB2);
|
||||
PORTB &= ~_BV(PB7);
|
||||
DDRB &= ~_BV(PB7); // tristate SCK
|
||||
// SPCR=0;
|
||||
DDRB &= ~_BV(PB2);
|
||||
_delay_us(1);
|
||||
loop_until_bit_is_set(PINB, PB2);
|
||||
DDRB |= _BV(PB2);
|
||||
// SPCR=0b01010000;
|
||||
SD_SPI_OFFLOAD = 0;
|
||||
deselectCard(drv);
|
||||
DDRB |= _BV(PB7);
|
||||
return RES_OK;
|
||||
SPDR = 0xff;
|
||||
|
||||
*(buffer++) = tmp;
|
||||
} else {
|
||||
// Initiate data exchange over SPI
|
||||
SPDR = 0xff;
|
||||
|
||||
for (i=0; i<512; i++) {
|
||||
// Wait until data has been received
|
||||
loop_until_bit_is_set(SPSR, SPIF);
|
||||
tmp = SPDR;
|
||||
// Transmit the next byte while we store the current one
|
||||
SPDR = 0xff;
|
||||
|
||||
*(buffer++) = tmp;
|
||||
#ifdef CONFIG_SD_DATACRC
|
||||
crc = _crc_xmodem_update(crc, tmp);
|
||||
crc = _crc_xmodem_update(crc, tmp);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
// Wait until the first CRC byte is received
|
||||
loop_until_bit_is_set(SPSR, SPIF);
|
||||
|
||||
|
||||
// Check CRC
|
||||
recvcrc = (SPDR << 8) + spiTransferByte(0xff);
|
||||
#ifdef CONFIG_SD_DATACRC
|
||||
@@ -586,7 +611,6 @@ DRESULT sd_read(BYTE drv, BYTE *buffer, DWORD sector, BYTE count) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
break;
|
||||
}
|
||||
deselectCard(drv);
|
||||
|
||||
Reference in New Issue
Block a user