SD acceleration, display file size in menu (fw side)

This commit is contained in:
ikari 2010-12-04 02:19:36 +01:00
parent f4b88ca792
commit 4bc455f12b
19 changed files with 370 additions and 370 deletions

View File

@ -11,4 +11,11 @@
(bit)*4 + 0x02000000 + ((unsigned long)&(addr) & 0xfe000000) \
)))
#define BITBAND_OFF(addr,offset,bit) \
(*((volatile unsigned long *)( \
(((unsigned long)&(addr) + offset) & 0x01ffffff)*32 + \
(bit)*4 + 0x02000000 + (((unsigned long)&(addr) + offset) & 0xfe000000) \
)))
#endif

View File

@ -1,6 +1,8 @@
#ifndef _CONFIG_H
#define _CONFIG_H
// #define DEBUG_SD
#define VER "0.0.1(NSFW)"
#define IN_AHBRAM __attribute__ ((section(".ahbram")))
@ -71,4 +73,22 @@
// 1: 3
#define SSP_DMACH LPC_GPDMACH0
#define SD_CLKREG LPC_GPIO0
#define SD_CMDREG LPC_GPIO0
#define SD_DAT0REG LPC_GPIO0
#define SD_DAT1REG LPC_GPIO1
#define SD_DAT2REG LPC_GPIO1
#define SD_DAT3REG LPC_GPIO0
#define SD_CLKPIN (7)
#define SD_CMDPIN (9)
#define SD_DAT0PIN (8)
#define SD_DAT1PIN (14)
#define SD_DAT2PIN (15)
#define SD_DAT3PIN (6)
#define SD_DAT ((BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN))\
|((SD_DAT1REG->FIOPIN1 >> 5) & 0x6)\
|((BITBAND(SD_DAT3REG->FIOPIN, SD_DAT3PIN)) << 3))
#endif

View File

@ -62,6 +62,7 @@ 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;
extern volatile enum diskstates disk_state;
/* Disk type - part of the external API except for ATA2! */

View File

@ -2175,8 +2175,12 @@ FRESULT f_read (
if (csect + cc > fp->fs->csize) /* Clip at cluster boundary */
cc = fp->fs->csize - csect;
/* XXX OFFLOAD GOES HERE */
if (ff_sd_offload) {
sd_offload = 1;
}
if (disk_read(fp->fs->drv, rbuff, sect, (BYTE)cc) != RES_OK)
ABORT(fp->fs, FR_DISK_ERR);
sd_offload = 0;
#if !_FS_READONLY && _FS_MINIMIZE <= 2 /* Replace one of the read sectors with cached data if it contains a dirty sector */
#if _FS_TINY
if (fp->fs->wflag && fp->fs->winsect - sect < cc)
@ -2214,7 +2218,7 @@ FRESULT f_read (
mem_cpy(rbuff, &fp->buf[fp->fptr % SS(fp->fs)], rcnt); /* Pick partial sector */
#endif
}
ff_sd_offload = 0;
LEAVE_FF(fp->fs, FR_OK);
}

View File

@ -48,7 +48,7 @@
/* To enable f_forward function, set _USE_FORWARD to 1 and set _FS_TINY to 1. */
#define _USE_FASTSEEK 1 /* 0:Disable or 1:Enable */
#define _USE_FASTSEEK 0 /* 0:Disable or 1:Enable */
/* To enable fast seek feature, set _USE_FASTSEEK to 1. */

View File

@ -61,6 +61,9 @@ UINT file_read() {
UINT file_write() {
UINT bytes_written;
file_res = f_write(&file_handle, file_buf, sizeof(file_buf), &bytes_written);
if(bytes_written < sizeof(file_buf)) {
printf("wrote less than expected - card full?\n");
}
return bytes_written;
}

View File

@ -70,7 +70,10 @@ uint32_t scan_dir(char* path, char mkdb, uint32_t this_dir_tgt) {
uint16_t numentries;
uint32_t dirsize;
uint8_t pass = 0;
char buf[10];
char buf[7];
char *size_units[3] = {" ", "k", "M"};
uint32_t entry_fsize;
uint8_t entry_unit_idx;
dir_tgt = this_dir_tgt;
if(depth==0) {
@ -185,7 +188,7 @@ uint32_t scan_dir(char* path, char mkdb, uint32_t this_dir_tgt) {
/* write element pointer to current dir structure */
/* printf("d=%d Saving %lX to Address %lX [file]\n", depth, db_tgt, dir_tgt); */
if((db_tgt&0xffff) > ((0x10000-(sizeof(len) + pathlen + sizeof(fno.fsize) + 1))&0xffff)) {
if((db_tgt&0xffff) > ((0x10000-(sizeof(len) + pathlen + sizeof(buf)-1 + 1))&0xffff)) {
printf("switch! old=%lx ", db_tgt);
db_tgt &= 0xffff0000;
db_tgt += 0x00010000;
@ -198,7 +201,14 @@ uint32_t scan_dir(char* path, char mkdb, uint32_t this_dir_tgt) {
- file name
- file size */
/* sram_writeblock((uint8_t*)&romprops, db_tgt, sizeof(romprops)); */
snprintf(buf, sizeof(buf), " % 7ldk", fno.fsize/1024);
entry_fsize = fno.fsize;
entry_unit_idx = 0;
while(entry_fsize > 9999) {
entry_fsize >>= 10;
entry_unit_idx++;
}
snprintf(buf, sizeof(buf), "% 5ld", entry_fsize);
strncat(buf, size_units[entry_unit_idx], 1);
sram_writeblock(buf, db_tgt, sizeof(buf)-1);
sram_writebyte(len+1, db_tgt + sizeof(buf)-1);
sram_writeblock(path, db_tgt + sizeof(len) + sizeof(buf)-1, pathlen + 1);

View File

@ -97,11 +97,22 @@ void fpga_pgm(uint8_t* filename) {
int MAXRETRIES = 10;
int retries = MAXRETRIES;
uint8_t data;
int i;
tick_t timeout;
// UINT bytes_read;
// uint16_t j;
do {
i=0;
timeout = getticks() + 100;
fpga_set_prog_b(0);
uart_putc('P');
fpga_set_prog_b(1);
while(!fpga_get_initb());
while(!fpga_get_initb()){
if(getticks() > timeout) {
printf("no response from FPGA trying to initiate configuration!\n");
led_panic();
}
};
LPC_GPIO2->FIOMASK1 = ~(BV(0));
uart_putc('p');
@ -114,13 +125,17 @@ void fpga_pgm(uint8_t* filename) {
return;
}
uart_putc('C');
for (;;) {
data = rle_file_getc();
i++;
if (file_status || file_res) break; /* error or eof */
FPGA_SEND_BYTE_SERIAL(data);
}
uart_putc('c');
file_close();
printf("fpga_pgm: %d bytes programmed\n", i);
delay_ms(1);
} while (!fpga_get_done() && retries--);
if(!fpga_get_done()) {
printf("FPGA failed to configure after %d tries.\n", MAXRETRIES);

View File

@ -35,7 +35,6 @@ void fpga_set_cclk(uint8_t val);
int fpga_get_initb(void);
void fpga_init(void);
uint8_t fpga_test(void);
void fpga_postinit(void);
void fpga_pgm(uint8_t* filename);

View File

@ -29,16 +29,19 @@
cmd param function
=============================================
00 bb[hh[ll]] set address to 0xbb0000, 0xbbhh00, or 0xbbhhll
10 bbhhll set SNES input address mask to 0xbbhhll
20 bbhhll set SRAM address mask to 0xbbhhll
00 bbhhll set address to 0xbbhhll
01 bbhhll set SNES input address mask to 0xbbhhll
02 bbhhll set SRAM address mask to 0xbbhhll
3m - set mapper to m
0=HiROM, 1=LoROM, 2=ExHiROM, 7=Menu
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)
F0 - receive test token (to see if FPGA is alive)
F1 - receive status
*/
@ -66,7 +69,7 @@ void set_mcu_addr(uint32_t address) {
void set_saveram_mask(uint32_t mask) {
FPGA_SELECT();
FPGA_TX_BYTE(0x20);
FPGA_TX_BYTE(0x02);
FPGA_TX_BYTE((mask>>16)&0xff);
FPGA_TX_BYTE((mask>>8)&0xff);
FPGA_TX_BYTE((mask)&0xff);
@ -75,7 +78,7 @@ void set_saveram_mask(uint32_t mask) {
void set_rom_mask(uint32_t mask) {
FPGA_SELECT();
FPGA_TX_BYTE(0x10);
FPGA_TX_BYTE(0x01);
FPGA_TX_BYTE((mask>>16)&0xff);
FPGA_TX_BYTE((mask>>8)&0xff);
FPGA_TX_BYTE((mask)&0xff);
@ -97,3 +100,25 @@ uint8_t fpga_test() {
return result;
}
uint8_t fpga_status() {
FPGA_SELECT();
FPGA_TX_BYTE(0xF1); /* STATUS */
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;
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(0x00); /* dummy */
while(FPGA_RX_BYTE() & 0x80);
FPGA_DESELECT();
BITBAND(SD_CLKREG->FIODIR, SD_CLKPIN) = 1;
}

View File

@ -47,7 +47,8 @@
#define FPGA_SPI_SLOW() spi_set_speed(SPI_SPEED_FPGA_SLOW)
void fpga_spi_init(void);
void fpga_spi_test(void);
uint8_t fpga_test(void);
uint8_t fpga_status(void);
void spi_fpga(void);
void spi_sd(void);
void spi_none(void);
@ -55,5 +56,6 @@ void set_mcu_addr(uint32_t);
void set_saveram_mask(uint32_t);
void set_rom_mask(uint32_t);
void set_mapper(uint8_t val);
void fpga_sd2ram(void);
#endif

View File

@ -23,15 +23,19 @@
#include "cli.h"
#include "sdnative.h"
#include "crc.h"
#include "smc.h"
#define EMC0TOGGLE (3<<4)
#define MR0R (1<<1)
int i;
int sd_offload = 0, ff_sd_offload = 0;
/* FIXME HACK */
volatile enum diskstates disk_state;
extern volatile tick_t ticks;
extern snes_romprops_t romprops;
int main(void) {
LPC_GPIO2->FIODIR = BV(0) | BV(1) | BV(2);
LPC_GPIO1->FIODIR = 0;
@ -58,25 +62,12 @@ int main(void) {
/* do this last because the peripheral init()s change PCLK dividers */
clock_init();
// sd_init();
sdn_init();
// while(1);
fpga_spi_init();
delay_ms(10);
printf("\n\nsd2snes mk.2\n============\nfw ver.: " VER "\ncpu clock: %d Hz\n", CONFIG_CPU_FREQUENCY);
file_init();
cic_init(1);
/* uart_putc('S');
for(p1=0; p1<8192; p1++) {
file_read();
}
file_close();
uart_putc('E');
uart_putcrlf();
printf("sizeof(struct FIL): %d\n", sizeof(file_handle));
uart_trace(file_buf, 0, 512);*/
/* setup timer (fpga clk) */
LPC_TIM3->CTCR=0;
LPC_TIM3->EMR=EMC0TOGGLE;
@ -103,16 +94,6 @@ restart:
uint32_t mem_dir_id = sram_readlong(SRAM_DIRID);
uint32_t mem_magic = sram_readlong(SRAM_SCRATCHPAD);
/* printf("savetest...");
int i;
uint16_t testcrc = 0;
for(i=0; i<128; i++) {
testcrc = crc_xmodem_update(testcrc, 0xff);
}
printf("testcrc = %04x\n", testcrc);
save_sram((uint8_t*)"/pretty long filename here you know.bin", 0x400000, SRAM_DB_ADDR);
printf("it's over!\n");
while(1)cli_entrycheck(); */
printf("mem_magic=%lx mem_dir_id=%lx saved_dir_id=%lx\n", mem_magic, mem_dir_id, saved_dir_id);
mem_magic=0x12938712; /* always rescan card for now */
if((mem_magic != 0x12345678) || (mem_dir_id != saved_dir_id)) {
@ -172,11 +153,12 @@ restart:
printf("test sram\n");
while(!sram_reliable());
printf("ok\n");
sram_hexdump(SRAM_DB_ADDR, 0x200);
//sram_hexdump(SRAM_DB_ADDR, 0x200);
//sram_hexdump(SRAM_MENU_ADDR, 0x400);
while(!cmd) {
cmd=menu_main_loop();
printf("derp %d\n", cmd);
printf("cmd: %d\n", cmd);
sleep_ms(50);
uart_putc('-');
switch(cmd) {
@ -192,13 +174,13 @@ sram_hexdump(SRAM_DB_ADDR, 0x200);
} else {
printf("No SRAM\n");
}
save_sram((uint8_t*)"/debug.smc", filesize, SRAM_ROM_ADDR);
set_mcu_ovr(0);
snes_reset(1);
delay_ms(100);
snes_reset(0);
break;
case SNES_CMD_SETRTC:
cmd=0; /* stay in loop */
break;
default:
printf("unknown cmd: %d\n", cmd);
@ -230,18 +212,17 @@ save_sram((uint8_t*)"/debug.smc", filesize, SRAM_ROM_ADDR);
}
}
if(snes_reset_state) {
delay_ms(10);
reset_count++;
} else {
sram_reliable();
snes_main_loop();
}
if(reset_count>100) {
if(reset_count>4) {
reset_count=0;
set_mcu_ovr(1);
snes_reset(1);
delay_ms(100);
if(romprops.ramsize_bytes && fpga_test() == 0xa5) {
if(romprops.ramsize_bytes && fpga_test() == FPGA_TEST_TOKEN) {
writeled(1);
save_sram(file_lfn, romprops.ramsize_bytes, SRAM_SAVE_ADDR);
writeled(0);

View File

@ -39,9 +39,13 @@
#include "memory.h"
#include "snes.h"
#include "timer.h"
#include "rle.h"
#include "diskio.h"
char* hex = "0123456789ABCDEF";
extern snes_romprops_t romprops;
void sram_hexdump(uint32_t addr, uint32_t len) {
static uint8_t buf[16];
uint32_t ptr;
@ -162,25 +166,30 @@ uint32_t load_rom(uint8_t* filename, uint32_t base_addr) {
UINT bytes_read;
DWORD filesize;
UINT count=0;
tick_t tickstmp, ticksstart, ticks_read=0, ticks_tx=0, ticks_total=0;
ticksstart=getticks();
printf("%s\n", filename);
file_open(filename, FA_READ);
filesize = file_handle.fsize;
smc_id(&romprops);
set_mcu_addr(base_addr);
printf("no nervous breakdown beyond this point! or else!\n");
if(file_res) {
uart_putc('?');
uart_putc(0x30+file_res);
return 0;
}
filesize = file_handle.fsize;
smc_id(&romprops);
set_mcu_addr(base_addr);
printf("no nervous breakdown beyond this point! or else!\n");
f_lseek(&file_handle, romprops.offset);
FPGA_DESELECT();
FPGA_SELECT();
FPGA_TX_BYTE(0x91); /* write w/ increment */
// FPGA_DESELECT();
// FPGA_SELECT();
// FPGA_TX_BYTE(0x91); /* write w/ increment */
for(;;) {
/* SPI_OFFLOAD=1; */
ff_sd_offload=1;
tickstmp=getticks();
bytes_read = file_read();
ticks_read+=getticks()-tickstmp;
if (file_res || !bytes_read) break;
if(!(count++ % 32)) {
if(!(count++ % 512)) {
toggle_read_led();
/* bounce_busy_led(); */
uart_putc('.');
@ -188,14 +197,17 @@ uint32_t load_rom(uint8_t* filename, uint32_t base_addr) {
// for(int j=0; j<bytes_read; j++) {
// FPGA_TX_BYTE(file_buf[j]);
// }
FPGA_TX_BLOCK(file_buf, 512);
//tickstmp = getticks();
// FPGA_TX_BLOCK(file_buf, 512);
//ticks_tx+=getticks()-tickstmp;
}
FPGA_TX_BYTE(0x00); /* dummy tx for increment+write pulse */
FPGA_DESELECT();
// FPGA_TX_BYTE(0x00); /* dummy tx for increment+write pulse */
// FPGA_DESELECT();
file_close();
set_mapper(romprops.mapper_id);
printf("rom header map: %02x; mapper id: %d\n", romprops.header.map, romprops.mapper_id);
ticks_total=getticks()-ticksstart;
printf("%u ticks in read, %u ticks in tx, %u ticks total\n", ticks_read, ticks_tx, ticks_total);
uint32_t rammask;
uint32_t rommask;
@ -212,7 +224,7 @@ uint32_t load_rom(uint8_t* filename, uint32_t base_addr) {
printf("ramsize=%x rammask=%lx\nromsize=%x rommask=%lx\n", romprops.header.ramsize, rammask, romprops.header.romsize, rommask);
set_saveram_mask(rammask);
set_rom_mask(rommask);
readled(0);
return (uint32_t)filesize;
}
@ -238,6 +250,26 @@ uint32_t load_sram(uint8_t* filename, uint32_t base_addr) {
return (uint32_t)filesize;
}
uint32_t load_sram_rle(uint8_t* filename, uint32_t base_addr) {
uint8_t data;
set_mcu_addr(base_addr);
DWORD filesize;
file_open(filename, FA_READ);
filesize = file_handle.fsize;
if(file_res) return 0;
FPGA_SELECT();
FPGA_TX_BYTE(0x91);
for(;;) {
data = rle_file_getc();
if (file_res || file_status) break;
FPGA_TX_BYTE(data);
}
FPGA_TX_BYTE(0x00); /* dummy tx */
FPGA_DESELECT();
file_close();
return (uint32_t)filesize;
}
void save_sram(uint8_t* filename, uint32_t sram_size, uint32_t base_addr) {
uint32_t count = 0;
@ -318,3 +350,14 @@ uint8_t sram_reliable() {
rdyled(result);
return result;
}
void sram_memset(uint32_t base_addr, uint32_t len, uint8_t val) {
set_mcu_addr(base_addr);
FPGA_SELECT();
FPGA_TX_BYTE(0x91);
for(uint32_t i=0; i<len; i++) {
FPGA_TX_BYTE(val);
}
FPGA_TX_BYTE(0x00);
FPGA_DESELECT();
}

View File

@ -45,6 +45,7 @@
uint32_t load_rom(uint8_t* filename, uint32_t base_addr);
uint32_t load_sram(uint8_t* filename, uint32_t base_addr);
uint32_t load_sram_rle(uint8_t* filename, uint32_t base_addr);
void sram_hexdump(uint32_t addr, uint32_t len);
uint8_t sram_readbyte(uint32_t addr);
uint16_t sram_readshort(uint32_t addr);
@ -58,6 +59,6 @@ void sram_writeblock(void* buf, uint32_t addr, uint16_t size);
void save_sram(uint8_t* filename, uint32_t sram_size, uint32_t base_addr);
uint32_t calc_sram_crc(uint32_t base_addr, uint32_t size);
uint8_t sram_reliable(void);
void sram_memset(uint32_t base_adde, uint32_t len, uint8_t val);
snes_romprops_t romprops;
#endif

View File

@ -1,5 +1,4 @@
#include <arm/NXP/LPC17xx/LPC17xx.h>
#include <arm/bits.h>
#include <stdio.h>
#include "config.h"
#include "crc.h"
@ -10,13 +9,18 @@
#include "led.h"
#include "sdnative.h"
#include "fileops.h"
#include "bits.h"
#include "fpga_spi.h"
#define MAX_CARDS 1
// SD/MMC commands
#define GO_IDLE_STATE 0
#define SEND_OP_COND 1
#define ALL_SEND_CID 2
#define SEND_RELATIVE_ADDR 3
#define SWITCH_FUNC 6
#define SELECT_CARD 7
#define SEND_IF_COND 8
#define SEND_CSD 9
#define SEND_CID 10
@ -41,6 +45,7 @@
#define CRC_ON_OFF 59
// SD ACMDs
#define SD_SET_BUS_WIDTH 6
#define SD_STATUS 13
#define SD_SEND_NUM_WR_BLOCKS 22
#define SD_SET_WR_BLK_ERASE_COUNT 23
@ -62,20 +67,6 @@
#define CARD_SD (1<<0)
#define CARD_SDHC (1<<1)
#define SD_CLKREG LPC_GPIO0
#define SD_CMDREG LPC_GPIO0
#define SD_DAT0REG LPC_GPIO0
#define SD_DAT1REG LPC_GPIO1
#define SD_DAT2REG LPC_GPIO1
#define SD_DAT3REG LPC_GPIO0
#define SD_CLKPIN (7)
#define SD_CMDPIN (9)
#define SD_DAT0PIN (8)
#define SD_DAT1PIN (14)
#define SD_DAT2PIN (15)
#define SD_DAT3PIN (6)
/*
1 DAT3/SS P0.6
2 CMD/DI P0.9
@ -118,7 +109,7 @@ uint8_t cmd[6]={0,0,0,0,0,0};
uint8_t rsp[17];
uint8_t csd[17];
uint8_t ccs=0;
uint8_t rca1, rca2;
uint32_t rca;
enum trans_state { TRANS_NONE = 0, TRANS_READ, TRANS_WRITE };
enum cmd_state { CMD_RSP = 0, CMD_RSPDAT, CMD_DAT };
@ -204,8 +195,12 @@ static inline void wiggle_fast_pos1(void) {
BITBAND(SD_CLKREG->FIOCLR, SD_CLKPIN) = 1;
}
static inline void wait_busy(void) {
while(!(BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN))) {
wiggle_fast_neg1();
}
wiggle_fast_neg(4);
}
/*
send_command_slow
@ -215,9 +210,8 @@ static inline void wiggle_fast_pos1(void) {
int send_command_slow(uint8_t* cmd, uint8_t* rsp){
uint8_t shift, i=6;
int rsplen;
// printf("send_command_slow: sending CMD:\n");
uint8_t cmdno = *cmd & 0x3f;
wiggle_slow_pos(5);
// uart_trace(cmd, 0, 6);
switch(*cmd & 0x3f) {
case 0:
rsplen = 0;
@ -254,12 +248,11 @@ int send_command_slow(uint8_t* cmd, uint8_t* rsp){
if(rsplen) {
uint16_t timeout=1000;
/* wait for responsebob */
while((BITBAND(SD_CMDREG->FIOPIN, SD_CMDPIN)) && --timeout) {
wiggle_slow_neg(1);
}
// printf("timeout=%d\n", timeout);
if(!timeout) {
printf("CMD%d timed out\n", cmdno);
return 0; /* no response within timeout */
}
@ -287,11 +280,11 @@ int send_command_slow(uint8_t* cmd, uint8_t* rsp){
*/
int send_command_fast(uint8_t* cmd, uint8_t* rsp, uint8_t* buf){
uint8_t datshift=8, cmdshift, i=6;
uint8_t cmdno = *cmd & 0x3f;
int rsplen, dat=0, waitbusy=0, datcnt=512, j=0;
static int state=CMD_RSP;
// printf("send_command_fast: sending CMD:\n");
wiggle_fast_pos(9);
// uart_trace(cmd, 0, 6);
wiggle_fast_pos(9); /* give the card >=8 cycles after last command */
DBG_SD printf("send_command_fast: sending CMD%d; payload=%02x%02x%02x%02x%02x%02x...\n", cmdno, cmd[0], cmd[1], cmd[2], cmd[3], cmd[4], cmd[5]);
switch(*cmd & 0x3f) {
case 0:
rsplen = 0;
@ -319,32 +312,32 @@ int send_command_fast(uint8_t* cmd, uint8_t* rsp, uint8_t* buf){
BITBAND(SD_CMDREG->FIODIR, SD_CMDPIN) = 1;
while(i--) {
uint8_t data = *cmd;
cmdshift = 8;
do {
cmdshift--;
uint8_t data = *cmd;
*cmd<<=1;
if(data&0x80) {
BITBAND(SD_CMDREG->FIOSET, SD_CMDPIN) = 1;
} else {
BITBAND(SD_CMDREG->FIOCLR, SD_CMDPIN) = 1;
}
data<<=1;
wiggle_fast_pos1();
} while (cmdshift);
cmd++;
}
wiggle_fast_pos(1);
wiggle_fast_pos1();
BITBAND(SD_CMDREG->FIODIR, SD_CMDPIN) = 0;
if(rsplen) {
uint16_t timeout=65535;
/* wait for responsebob */
uint32_t timeout=2000000;
/* wait for response */
while((BITBAND(SD_CMDREG->FIOPIN, SD_CMDPIN)) && --timeout) {
wiggle_fast_neg1();
}
// printf("timeout=%d\n", timeout);
if(!timeout) {
printf("CMD%d timed out\n", cmdno);
return 0; /* no response within timeout */
}
@ -355,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))) {
// printf("data start\n");
DBG_SD printf("data start during response\n");
j=datcnt;
state=CMD_RSPDAT;
break;
@ -365,7 +358,7 @@ int send_command_fast(uint8_t* cmd, uint8_t* rsp, uint8_t* buf){
cmddata |= (BITBAND(SD_CMDREG->FIOPIN, SD_CMDPIN)) << cmdshift;
wiggle_fast_neg1();
} while (cmdshift);
if(state==1)break;
if(state==CMD_RSPDAT)break;
*rsp=cmddata;
cmddata=0;
rsp++;
@ -373,7 +366,7 @@ int send_command_fast(uint8_t* cmd, uint8_t* rsp, uint8_t* buf){
if(state==CMD_RSPDAT) { /* process response+data */
int startbit=1;
printf("processing rsp+data cmdshift=%d i=%d j=%d\n", cmdshift, i, j);
DBG_SD printf("processing rsp+data cmdshift=%d i=%d j=%d\n", cmdshift, i, j);
datshift=8;
while(1) {
cmdshift--;
@ -385,16 +378,14 @@ int send_command_fast(uint8_t* cmd, uint8_t* rsp, uint8_t* buf){
rsp++;
i--;
if(!i) {
printf("response end\n");
DBG_SD printf("response end\n");
if(j) state=CMD_DAT; /* response over, remaining data */
break;
}
}
if(!startbit) {
datshift-=4;
datdata |= ((BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN))
|((SD_DAT1REG->FIOPIN >> 13) & 0x6)
|((BITBAND(SD_DAT3REG->FIOPIN, SD_DAT3PIN)) << 3)) << datshift;
datdata |= SD_DAT << datshift;
if(!datshift) {
datshift=8;
*buf=datdata;
@ -413,25 +404,26 @@ int send_command_fast(uint8_t* cmd, uint8_t* rsp, uint8_t* buf){
state=CMD_DAT;
j=datcnt;
datshift=8;
// printf("response over, waiting for data...\n");
DBG_SD printf("response over, waiting for data...\n");
while((BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN)) && --timeout) {
wiggle_fast_neg1();
}
wiggle_fast_neg1(); /* eat the start bit */
if(sd_offload) {
fpga_sd2ram();
state=CMD_RSP;
return rsplen;
}
}
if(state==CMD_DAT) { /* transfer rest of data */
// printf("remaining data: %d\n", j);
DBG_SD printf("remaining data: %d\n", j);
if(datshift==8) {
while(1) {
datdata |= ((BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN))
|((SD_DAT1REG->FIOPIN >> 13) & 0x6)
|((BITBAND(SD_DAT3REG->FIOPIN, SD_DAT3PIN)) << 3)) << 4;
datdata |= SD_DAT << 4;
wiggle_fast_neg1();
datdata |= ((BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN))
|((SD_DAT1REG->FIOPIN >> 13) & 0x6)
|((BITBAND(SD_DAT3REG->FIOPIN, SD_DAT3PIN)) << 3));
datdata |= SD_DAT;
wiggle_fast_neg1();
*buf=datdata;
@ -444,9 +436,7 @@ int send_command_fast(uint8_t* cmd, uint8_t* rsp, uint8_t* buf){
while(1) {
datshift-=4;
datdata |= ((BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN))
|((SD_DAT1REG->FIOPIN >> 13) & 0x6)
|((BITBAND(SD_DAT3REG->FIOPIN, SD_DAT3PIN)) << 3)) << datshift;
datdata |= SD_DAT << datshift;
if(!datshift) {
datshift=8;
*buf=datdata;
@ -463,17 +453,18 @@ int send_command_fast(uint8_t* cmd, uint8_t* rsp, uint8_t* buf){
if(dat) wiggle_fast_neg(17);
if(waitbusy) {
while(!(BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN))) {
wiggle_fast_neg1();
}
DBG_SD printf("waitbusy after send_cmd\n");
wait_busy();
}
state=CMD_RSP;
}
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]);
return rsplen;
}
void make_crc7(uint8_t* cmd) {
static inline void make_crc7(uint8_t* cmd) {
cmd[5]=crc7update(0, cmd[0]);
cmd[5]=crc7update(cmd[5], cmd[1]);
cmd[5]=crc7update(cmd[5], cmd[2]);
@ -482,65 +473,85 @@ void make_crc7(uint8_t* cmd) {
cmd[5]=(cmd[5] << 1) | 1;
}
int cmd_slow(uint8_t cmd, uint32_t param, uint8_t crc, uint8_t* dat, uint8_t* rsp) {
uint8_t cmdbuf[6];
cmdbuf[0] = 0x40 | cmd;
cmdbuf[1] = param >> 24;
cmdbuf[2] = param >> 16;
cmdbuf[3] = param >> 8;
cmdbuf[4] = param;
if(!crc) {
make_crc7(cmdbuf);
} else {
cmdbuf[5] = crc;
}
return send_command_slow(cmdbuf, rsp);
}
int acmd_slow(uint8_t cmd, uint32_t param, uint8_t crc, uint8_t* dat, uint8_t* rsp) {
if(!(cmd_slow(APP_CMD, rca, 0, NULL, rsp))) {
return 0;
}
return cmd_slow(cmd, param, crc, dat, rsp);
}
int cmd_fast(uint8_t cmd, uint32_t param, uint8_t crc, uint8_t* dat, uint8_t* rsp) {
uint8_t cmdbuf[6];
cmdbuf[0] = 0x40 | cmd;
cmdbuf[1] = param >> 24;
cmdbuf[2] = param >> 16;
cmdbuf[3] = param >> 8;
cmdbuf[4] = param;
if(!crc) {
make_crc7(cmdbuf);
} else {
cmdbuf[5] = crc;
}
return send_command_fast(cmdbuf, rsp, dat);
}
int acmd_fast(uint8_t cmd, uint32_t param, uint8_t crc, uint8_t* dat, uint8_t* rsp) {
if(!(cmd_fast(APP_CMD, rca, 0, NULL, rsp))) {
return 0;
}
return cmd_fast(cmd, param, crc, dat, rsp);
}
void stream_datablock(uint8_t *buf) {
// uint8_t datshift=8;
int j=512;
uint8_t datdata=0;
uint16_t timeout=65535;
uint32_t timeout=1000000;
while((BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN)) && --timeout) {
wiggle_fast_neg1();
}
wiggle_fast_neg1(); /* eat the start bit */
if(sd_offload) {
fpga_sd2ram();
} else {
while(1) {
datdata = SD_DAT << 4;
wiggle_fast_neg1();
datdata |= SD_DAT;
wiggle_fast_neg1();
while(1) {
/*
datshift-=4;
datdata |= ((BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN))
|((SD_DAT1REG->FIOPIN >> 13) & 0x6)
|((BITBAND(SD_DAT3REG->FIOPIN, SD_DAT3PIN)) << 3)) << datshift;
if(!datshift) {
datshift=8;
*buf=datdata;
datdata=0;
buf++;
j--;
if(!j) break;
}
*/
datdata |= ((BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN))
|((SD_DAT1REG->FIOPIN >> 13) & 0x6)
|((BITBAND(SD_DAT3REG->FIOPIN, SD_DAT3PIN)) << 3)) << 4;
wiggle_fast_neg1();
datdata |= ((BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN))
|((SD_DAT1REG->FIOPIN >> 13) & 0x6)
|((BITBAND(SD_DAT3REG->FIOPIN, SD_DAT3PIN)) << 3));
wiggle_fast_neg1();
*buf=datdata;
datdata=0;
buf++;
j--;
if(!j) break;
}
/* eat the crc for now */
wiggle_fast_neg(17);
}
}
void send_datablock(uint8_t *buf) {
uint16_t crc0=0, crc1=0, crc2=0, crc3=0, cnt=512;
uint8_t dat0=0, dat1=0, dat2=0, dat3=0, crcshift, datshift;
//uart_trace(buf, 0, 512);
wiggle_fast_pos(1);
// printf("send_datablock: wait for card\n");
/* wait - card might be busy */
while(!(BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN))) {
wiggle_fast_neg(1);
printf(".");
}
wiggle_fast_pos1();
BITBAND(SD_DAT0REG->FIODIR, SD_DAT0PIN) = 1;
BITBAND(SD_DAT1REG->FIODIR, SD_DAT1PIN) = 1;
BITBAND(SD_DAT2REG->FIODIR, SD_DAT2PIN) = 1;
@ -551,7 +562,7 @@ void send_datablock(uint8_t *buf) {
BITBAND(SD_DAT2REG->FIOCLR, SD_DAT2PIN) = 1;
BITBAND(SD_DAT3REG->FIOCLR, SD_DAT3PIN) = 1;
wiggle_fast_pos(1); /* send start bit to card */
wiggle_fast_pos1(); /* send start bit to card */
crcshift=8;
while(cnt--) {
datshift=8;
@ -577,7 +588,7 @@ void send_datablock(uint8_t *buf) {
} else {
BITBAND(SD_DAT0REG->FIOCLR, SD_DAT0PIN) = 1;
}
wiggle_fast_pos(1);
wiggle_fast_pos1();
} while (datshift);
crcshift-=2;
@ -603,27 +614,27 @@ void send_datablock(uint8_t *buf) {
datshift=16;
do {
datshift--;
if((crc0 >> datshift)&1) {
if((crc0 >> datshift) & 1) {
BITBAND(SD_DAT0REG->FIOSET, SD_DAT0PIN) = 1;
} else {
BITBAND(SD_DAT0REG->FIOCLR, SD_DAT0PIN) = 1;
}
if((crc1 >> datshift)&1) {
if((crc1 >> datshift) & 1) {
BITBAND(SD_DAT1REG->FIOSET, SD_DAT1PIN) = 1;
} else {
BITBAND(SD_DAT1REG->FIOCLR, SD_DAT1PIN) = 1;
}
if((crc2 >> datshift)&1) {
if((crc2 >> datshift) & 1) {
BITBAND(SD_DAT2REG->FIOSET, SD_DAT2PIN) = 1;
} else {
BITBAND(SD_DAT2REG->FIOCLR, SD_DAT2PIN) = 1;
}
if((crc3 >> datshift)&1) {
if((crc3 >> datshift) & 1) {
BITBAND(SD_DAT3REG->FIOSET, SD_DAT3PIN) = 1;
} else {
BITBAND(SD_DAT3REG->FIOCLR, SD_DAT3PIN) = 1;
}
wiggle_fast_pos(1);
wiggle_fast_pos1();
} while(datshift);
/* send end bit */
BITBAND(SD_DAT0REG->FIOSET, SD_DAT0PIN) = 1;
@ -631,88 +642,73 @@ void send_datablock(uint8_t *buf) {
BITBAND(SD_DAT2REG->FIOSET, SD_DAT2PIN) = 1;
BITBAND(SD_DAT3REG->FIOSET, SD_DAT3PIN) = 1;
wiggle_fast_pos(1);
wiggle_fast_pos1();
BITBAND(SD_DAT0REG->FIODIR, SD_DAT0PIN) = 0;
BITBAND(SD_DAT1REG->FIODIR, SD_DAT1PIN) = 0;
BITBAND(SD_DAT2REG->FIODIR, SD_DAT2PIN) = 0;
BITBAND(SD_DAT3REG->FIODIR, SD_DAT3PIN) = 0;
wiggle_fast_neg(4);
wiggle_fast_neg(3);
dat0=0;
datshift=3;
datshift=4;
do {
datshift--;
dat0 |= ((BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN)) << datshift);
wiggle_fast_neg(1);
wiggle_fast_neg1();
} while (datshift);
if(dat0!=2) {
DBG_SD printf("crc %02x\n", dat0);
if((dat0 & 7) != 2) {
printf("crc error! %02x\n", dat0);
while(1);
}
wiggle_fast_neg(1);
while(!(BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN))) {
wiggle_fast_neg(1);
}
if(dat0 & 8) {
printf("missing start bit in CRC status response...\n");
}
wiggle_fast_neg(2);
wait_busy();
}
void read_block(uint32_t address, uint8_t *buf) {
if(during_blocktrans == TRANS_READ && (last_block == address-1)) {
//uart_putc('r');
stream_datablock(buf);
last_block=address;
} else {
if(during_blocktrans) {
//printf("nonseq read (%lx -> %lx), restarting transmission\n", last_block, address);
/* send STOP_TRANSMISSION to end an open READ/WRITE_MULTIPLE_BLOCK */
cmd[0]=0x40+STOP_TRANSMISSION;
cmd[1]=0;
cmd[2]=0;
cmd[3]=0;
cmd[4]=0;
cmd[5]=0x61;
send_command_fast(cmd, rsp, NULL);
cmd_fast(STOP_TRANSMISSION, 0, 0x61, NULL, rsp);
}
last_block=address;
if(!ccs) address <<= 9;
cmd[0]=0x40+READ_MULTIPLE_BLOCK;
cmd[1]=address>>24;
cmd[2]=address>>16;
cmd[3]=address>>8;
cmd[4]=address;
make_crc7(cmd);
send_command_fast(cmd, rsp, buf);
// uart_trace(cmd, 0, 6);
// uart_trace(rsp, 0, rsplen);
if(!ccs) {
address <<= 9;
}
cmd_fast(READ_MULTIPLE_BLOCK, address, 0, buf, rsp);
during_blocktrans = TRANS_READ;
}
// uart_trace(buf, 0, 512);
}
void write_block(uint32_t address, uint8_t* buf) {
if(during_blocktrans == TRANS_WRITE && (last_block == address-1)) {
wait_busy();
send_datablock(buf);
last_block=address;
} else {
if(during_blocktrans) {
/* send STOP_TRANSMISSION to end an open READ/WRITE_MULTIPLE_BLOCK */
cmd[0]=0x40+STOP_TRANSMISSION;
cmd[1]=0;
cmd[2]=0;
cmd[3]=0;
cmd[4]=0;
cmd[5]=0x61;
send_command_fast(cmd, rsp, NULL);
cmd_fast(STOP_TRANSMISSION, 0, 0x61, NULL, rsp);
}
wait_busy();
last_block=address;
if(!ccs) address <<= 9;
cmd[0]=0x40+WRITE_MULTIPLE_BLOCK;
cmd[1]=address>>24;
cmd[2]=address>>16;
cmd[3]=address>>8;
cmd[4]=address;
make_crc7(cmd);
send_command_fast(cmd, rsp, NULL); /* only send cmd & get response */
if(!ccs) {
address <<= 9;
}
/* only send cmd & get response */
cmd_fast(WRITE_MULTIPLE_BLOCK, address, 0, NULL, rsp);
DBG_SD printf("write_block: CMD25 response = %02x%02x%02x%02x%02x%02x\n", rsp[0], rsp[1], rsp[2], rsp[3], rsp[4], rsp[5]);
wiggle_fast_pos(8);
send_datablock(buf);
during_blocktrans = TRANS_WRITE;
}
@ -737,200 +733,74 @@ DRESULT disk_read(BYTE drv, BYTE *buffer, DWORD sector, BYTE count) __attribute_
DRESULT sdn_initialize(BYTE drv) {
uint8_t cmd[6]={0,0,0,0,0,0}; /* command */
uint8_t rsp[17]; /* space for response */
int rsplen;
uint8_t hcs=0;
if(drv>=MAX_CARDS)
rca = 0;
if(drv>=MAX_CARDS) {
return STA_NOINIT|STA_NODISK;
}
if(sdn_status(drv) & STA_NODISK) {
return STA_NOINIT|STA_NODISK;
}
/* if the card is sending data from before a reset we try to deselect it
prior to initialization */
for(rsplen=0; rsplen<2042; rsplen++) {
if(!(BITBAND(SD_DAT3REG->FIOPIN, SD_DAT3PIN))) {
printf("card seems to be sending data, attempting deselect\n");
cmd[0]=0x40+7;
cmd[1]=0;
cmd[2]=0;
cmd[3]=0;
cmd[4]=0;
make_crc7(cmd);
if(send_command_slow(cmd, rsp)) {
printf("card was sending data, CMD7 succeeded\n");
} else {
printf("CMD7 deselect no response! D:\n");
}
cmd_slow(SELECT_CARD, 0, 0, NULL, rsp);
}
wiggle_slow_neg(1);
}
cmd[0]=0x40+GO_IDLE_STATE;
cmd[5]=0x95;
printf("sd_init start\n");
if((rsplen=send_command_slow(cmd, rsp))) {
// printf("CMD0 response?!:\n");
// uart_trace(rsp, 0, rsplen);
}
cmd_slow(GO_IDLE_STATE, 0, 0x95, NULL, rsp);
wiggle_slow_pos(1000);
cmd[0]=0x40+SEND_IF_COND;
cmd[3]=0x01;
cmd[4]=0xaa;
cmd[5]=0x87;
if((rsplen=send_command_slow(cmd, rsp))) {
// uart_trace(cmd, 0, 6);
// printf("CMD8 response:\n");
// uart_trace(rsp, 0, rsplen);
if((rsplen=cmd_slow(SEND_IF_COND, 0x000001aa, 0x87, NULL, rsp))) {
DBG_SD printf("CMD8 response:\n");
DBG_SD uart_trace(rsp, 0, rsplen);
hcs=1;
}
while(1) {
cmd[0]=0x40+APP_CMD;
cmd[1]=0;
cmd[2]=0;
cmd[3]=0;
cmd[4]=0;
cmd[5]=0x65;
if((rsplen=send_command_slow(cmd, rsp))) {
// printf("CMD55 response:\n");
// uart_trace(rsp, 0, rsplen);
} else {
printf("CMD55 no response!\n");
}
cmd[0]=0x40+41;
cmd[1]=hcs<<6;
cmd[2]=0xfc; /* 2.7-3.6V */
cmd[3]=0x00;
cmd[4]=0x00;
cmd[5]=hcs ? 0x53 : 0xc1;
// printf("send ACMD41 hcs=%d\n", hcs);
if((rsplen=send_command_slow(cmd, rsp))) {
// printf("ACMD41 response:\n");
// uart_trace(rsp, 0, rsplen);
// printf("busy=%d\n ccs=%d\n", rsp[1]>>7, (rsp[1]>>6)&1);
} else {
if(!(acmd_slow(SD_SEND_OP_COND, (hcs << 30) | 0xfc0000, 0, NULL, rsp))) {
printf("ACMD41 no response!\n");
}
if(rsp[1]&0x80) break;
}
ccs = (rsp[1]>>6) & 1; /* SDHC */
ccs = (rsp[1]>>6) & 1; /* SDHC/XC */
cmd[0]=0x40+2;
cmd[1]=0;
cmd[2]=0;
cmd[3]=0;
cmd[4]=0;
cmd[5]=0x4d;
if((rsplen=send_command_slow(cmd, rsp))) {
// printf("CMD2 response:\n");
// uart_trace(rsp, 0, rsplen);
} else {
printf("CMD2 no response!\n");
}
cmd[0]=0x40+3;
cmd[1]=0;
cmd[2]=0;
cmd[3]=0;
cmd[4]=0;
cmd[5]=0x21;
if((rsplen=send_command_slow(cmd, rsp))) {
// printf("CMD3 response:\n");
// uart_trace(rsp, 0, rsplen);
rca1=rsp[1];
rca2=rsp[2];
// printf("RCA: %02x%02x\n", rca1, rca2);
cmd_slow(ALL_SEND_CID, 0, 0x4d, NULL, rsp);
if(cmd_slow(SEND_RELATIVE_ADDR, 0, 0x21, NULL, rsp)) {
rca=(rsp[1]<<24) | (rsp[2]<<16);
printf("RCA: %04lx\n", rca>>16);
} else {
printf("CMD3 no response!\n");
rca1=0;
rca2=0;
rca=0;
}
cmd[0]=0x40+9;
cmd[1]=rca1;
cmd[2]=rca2;
cmd[3]=0;
cmd[4]=0;
make_crc7(cmd);
/* record CSD for getinfo */
if((rsplen=send_command_slow(cmd, csd))) {
// printf("CMD9 response:\n");
// uart_trace(rsp, 0, rsplen);
} else {
printf("CMD9 no response!\n");
}
cmd[0]=0x40+7;
cmd[1]=rca1;
cmd[2]=rca2;
cmd[3]=0;
cmd[4]=0;
make_crc7(cmd);
cmd_slow(SEND_CSD, rca, 0, NULL, rsp);
/* select the card */
if((rsplen=send_command_slow(cmd, rsp))) {
// printf("CMD7 response:\n");
// uart_trace(rsp, 0, rsplen);
if(cmd_slow(SELECT_CARD, rca, 0, NULL, rsp)) {
printf("card selected!\n");
} else {
printf("CMD7 no response!\n");
}
cmd[0]=0x40+13;
cmd[1]=rca1;
cmd[2]=rca2;
cmd[3]=0;
cmd[4]=0;
make_crc7(cmd);
/* get card status */
if((rsplen=send_command_fast(cmd, rsp, NULL))) {
// printf("CMD13 response:\n");
// uart_trace(rsp, 0, rsplen);
} else {
printf("CMD13 no response!\n");
}
cmd_slow(SEND_STATUS, rca, 0, NULL, rsp);
/* set bus width */
cmd[0]=0x40+55;
cmd[1]=rca1;
cmd[2]=rca2;
cmd[3]=0;
cmd[4]=0;
make_crc7(cmd);
acmd_slow(SD_SET_BUS_WIDTH, 0x2, 0, NULL, rsp);
if((rsplen=send_command_slow(cmd, rsp))) {
// printf("CMD55 response:\n");
// uart_trace(rsp, 0, rsplen);
} else {
printf("CMD55 no response!\n");
}
/* set block length */
cmd_slow(SET_BLOCKLEN, 0x200, 0, NULL, rsp);
cmd[0]=0x40+6;
cmd[1]=0;
cmd[2]=0;
cmd[3]=0;
cmd[4]=2;
make_crc7(cmd);
if((rsplen=send_command_slow(cmd, rsp))) {
// printf("CMD55 response:\n");
// uart_trace(rsp, 0, rsplen);
} else {
printf("ACMD6 no response!\n");
}
/* int i;
printf("start 4MB streaming test\n");
for(i=0; i<8192; i++) {
read_block(i, file_buf);
}
printf("end 4MB streaming test\n");*/
printf("SD init complete. SDHC/XC=%d\n", ccs);
disk_state = DISK_OK;
during_blocktrans = TRANS_NONE;
return sdn_status(drv);
}
@ -955,28 +825,30 @@ void disk_init(void) __attribute__ ((weak, alias("sdn_init")));
DSTATUS sdn_status(BYTE drv) {
if (SDCARD_DETECT)
if (SDCARD_WP)
if (SDCARD_DETECT) {
if (SDCARD_WP) {
return STA_PROTECT;
else
} else {
return RES_OK;
else
}
} else {
return STA_NOINIT|STA_NODISK;
}
}
DSTATUS disk_status(BYTE drv) __attribute__ ((weak, alias("sdn_status")));
DRESULT sdn_getinfo(BYTE drv, BYTE page, void *buffer) {
uint32_t capacity;
if (drv >= MAX_CARDS)
if (drv >= MAX_CARDS) {
return RES_NOTRDY;
if (sdn_status(drv) & STA_NODISK)
}
if (sdn_status(drv) & STA_NODISK) {
return RES_NOTRDY;
if (page != 0)
}
if (page != 0) {
return RES_ERROR;
}
if (ccs) {
/* Special CSD for SDHC cards */
capacity = (1 + getbits(csd,127-69+8,22)) * 1024;
@ -993,6 +865,8 @@ DRESULT sdn_getinfo(BYTE drv, BYTE page, void *buffer) {
di->disktype = DISK_TYPE_SD;
di->sectorsize = 2;
di->sectorcount = capacity;
printf("card capacity: %lu sectors\n", capacity);
return RES_OK;
}
DRESULT disk_getinfo(BYTE drv, BYTE page, void *buffer) __attribute__ ((weak, alias("sdn_getinfo")));
@ -1003,9 +877,9 @@ DRESULT sdn_write(BYTE drv, const BYTE *buffer, DWORD sector, BYTE count) {
if(drv >= MAX_CARDS) {
return RES_NOTRDY;
}
if (sdn_status(drv) & STA_NODISK)
if (sdn_status(drv) & STA_NODISK) {
return RES_NOTRDY;
}
for(sec=0; sec<count; sec++) {
write_block(sector+sec, buf);
buf+=512;
@ -1017,9 +891,10 @@ DRESULT disk_write(BYTE drv, const BYTE *buffer, DWORD sector, BYTE count) __att
/* Detect changes of SD card 0 */
void sdn_changed() {
if (SDCARD_DETECT)
if (SDCARD_DETECT) {
disk_state = DISK_CHANGED;
else
} else {
disk_state = DISK_REMOVED;
}
}

View File

@ -3,8 +3,16 @@
#ifndef SDNATIVE_H
#define SDNATIVE_H
#ifdef DEBUG_SD
#define DBG_SD
#else
#define DBG_SD while(0)
#endif
#include "diskio.h"
extern int sd_offload;
/* These functions are weak-aliased to disk_... */
void sdn_init(void);
DSTATUS sdn_status(BYTE drv);

View File

@ -29,6 +29,8 @@
#include "uart.h"
#include "smc.h"
snes_romprops_t romprops;
uint32_t hdr_addr[6] = {0xffb0, 0x101b0, 0x7fb0, 0x81b0, 0x40ffb0, 0x4101b0};
uint8_t countAllASCII(uint8_t* data, int size) {
uint8_t res = 0;

View File

@ -39,6 +39,8 @@
uint8_t initloop=1;
uint32_t saveram_crc, saveram_crc_old;
extern snes_romprops_t romprops;
void snes_init() {
/* put reset level on reset pin */
BITBAND(SNES_RESET_REG->FIOCLR, SNES_RESET_BIT) = 1;
@ -135,5 +137,5 @@ uint8_t menu_main_loop() {
void get_selected_name(uint8_t* fn) {
uint32_t addr = sram_readlong(SRAM_PARAM_ADDR);
printf("fd addr=%lx\n", addr);
sram_readblock(fn, addr+10+SRAM_MENU_ADDR, 256);
sram_readblock(fn, addr + 7 + SRAM_MENU_ADDR, 256);
}

View File

@ -62,13 +62,15 @@ int sort_cmp_elem(const void* elem1, const void* elem2) {
/* get truncated string from database */
void sort_getstring_for_dirent(char *ptr, uint32_t addr) {
stat_getstring++;
uint8_t leaf_offset;
if(addr & 0x80000000) {
/* is directory link, name offset 6 */
sram_readblock(ptr, addr+0x6+SRAM_MENU_ADDR, 20);
/* is directory link, name offset 4 */
leaf_offset = sram_readbyte(addr + 4 + SRAM_MENU_ADDR);
sram_readblock(ptr, addr + 5 + leaf_offset + SRAM_MENU_ADDR, 20);
} else {
/* is file link, name offset 10 */
sram_readblock(ptr, addr+10+SRAM_MENU_ADDR, 20);
/* is file link, name offset 6 */
leaf_offset = sram_readbyte(addr + 6 + SRAM_MENU_ADDR);
sram_readblock(ptr, addr + 7 + leaf_offset + SRAM_MENU_ADDR, 20);
}
ptr[20]=0;
}