firmware: adjustments for Mk.II Rev.C; enable timesetting from SNES menu
This commit is contained in:
parent
9af83658e7
commit
bfe9a91d07
@ -55,7 +55,7 @@ TARGET = $(OBJDIR)/sd2snes
|
||||
|
||||
|
||||
# List C source files here. (C dependencies are automatically generated.)
|
||||
SRC = main.c ff.c ccsbcs.c clock.c uart.c power.c led.c timer.c printf.c spi.c fileops.c rtc.c fpga.c fpga_spi.c snes.c smc.c memory.c filetypes.c faulthandler.c sort.c crc32.c cic.c cli.c xmodem.c irq.c rle.c sdnative.c msu1.c
|
||||
SRC = main.c ff.c ccsbcs.c clock.c uart.c power.c led.c timer.c printf.c spi.c fileops.c rtc.c fpga.c fpga_spi.c snes.c smc.c memory.c filetypes.c faulthandler.c sort.c crc32.c cic.c cli.c xmodem.c irq.c rle.c sdnative.c msu1.c crc16.c
|
||||
|
||||
# usbcontrol.c usb_hid.c usbhw_lpc.c usbinit.c usbstdreq.c
|
||||
|
||||
@ -215,12 +215,11 @@ sym: $(TARGET).sym
|
||||
# cp $(TARGET).bin /mbed/hw_LPC1768.bin
|
||||
|
||||
|
||||
program: bin
|
||||
program: build
|
||||
utils/lpcchksum $(TARGET).bin
|
||||
openocd -f openocd-usb.cfg -f lpc1754.cfg -f flash.cfg
|
||||
make -C bootldr program
|
||||
|
||||
debug: bin
|
||||
debug: build
|
||||
openocd -f openocd-usb.cfg -f lpc1754.cfg
|
||||
|
||||
reset:
|
||||
|
||||
@ -55,7 +55,7 @@ TARGET = $(OBJDIR)/sd2snes_bootldr
|
||||
|
||||
|
||||
# List C source files here. (C dependencies are automatically generated.)
|
||||
SRC = timer.c main.c ff.c clock.c uart.c power.c led.c faulthandler.c crc32.c sdnative.c fileops.c iap.c printf.c crc.c
|
||||
SRC = timer.c main.c ff.c clock.c uart.c power.c led.c faulthandler.c crc16.c crc32.c sdnative.c fileops.c iap.c printf.c
|
||||
|
||||
# usbcontrol.c usb_hid.c usbhw_lpc.c usbinit.c usbstdreq.c
|
||||
|
||||
@ -67,7 +67,7 @@ SRC = timer.c main.c ff.c clock.c uart.c power.c led.c faulthandler.c crc32.c sd
|
||||
# Even though the DOS/Win* filesystem matches both .s and .S the same,
|
||||
# it will preserve the spelling of the filenames, and gcc itself does
|
||||
# care about how the name is spelled on its command-line.
|
||||
ASRC = startup.S
|
||||
ASRC = startup.S crc.S
|
||||
|
||||
|
||||
# Optimization level, can be [0, 1, 2, 3, s].
|
||||
|
||||
@ -5,17 +5,18 @@
|
||||
// #define DEBUG_IRQ
|
||||
// #define DEBUG_MSU1
|
||||
|
||||
//#define DEBUG_BL
|
||||
#ifdef DEBUG_BL
|
||||
#define DBG_BL
|
||||
#ifdef DEBUG_UART
|
||||
#define DBG_UART
|
||||
#else
|
||||
#define DBG_BL while(0)
|
||||
#define DBG_UART while(0)
|
||||
#endif
|
||||
|
||||
#define DBG_BL while(0)
|
||||
|
||||
#define FW_START (0x00002000L)
|
||||
#define FLASH_SECTORS (17)
|
||||
|
||||
|
||||
#define VER "0.0.1(NSFW)"
|
||||
#define IN_AHBRAM __attribute__ ((section(".ahbram")))
|
||||
|
||||
@ -29,10 +30,10 @@
|
||||
|
||||
#define SD_CHANGE_CLR() do {LPC_GPIOINT->IO2IntClr = BV(SD_DT_BIT);} while(0)
|
||||
|
||||
#define SD_DT_REG LPC_GPIO2
|
||||
#define SD_DT_BIT 3
|
||||
#define SD_WP_REG LPC_GPIO2
|
||||
#define SD_WP_BIT 4
|
||||
#define SD_DT_REG LPC_GPIO0
|
||||
#define SD_DT_BIT 8
|
||||
#define SD_WP_REG LPC_GPIO0
|
||||
#define SD_WP_BIT 6
|
||||
|
||||
#define SDCARD_DETECT (!(BITBAND(SD_DT_REG->FIOPIN, SD_DT_BIT)))
|
||||
#define SDCARD_WP (BITBAND(SD_WP_REG->FIOPIN, SD_WP_BIT))
|
||||
@ -40,16 +41,16 @@
|
||||
#define CONFIG_SD_BLOCKTRANSFER 1
|
||||
#define CONFIG_SD_AUTO_RETRIES 10
|
||||
// #define SD_CHANGE_VECT
|
||||
// #define CONFIG_SD_DATACRC 1
|
||||
#define CONFIG_SD_DATACRC 1
|
||||
|
||||
#define CONFIG_UART_NUM 3
|
||||
// #define CONFIG_CPU_FREQUENCY 90315789
|
||||
#define CONFIG_CPU_FREQUENCY (92000000L)
|
||||
//#define CONFIG_CPU_FREQUENCY 46000000
|
||||
#define CONFIG_UART_PCLKDIV 1
|
||||
#define CONFIG_UART_TX_BUF_SHIFT 1
|
||||
#define CONFIG_UART_TX_BUF_SHIFT 8
|
||||
#define CONFIG_UART_BAUDRATE 921600
|
||||
#define CONFIG_UART_DEADLOCKABLE
|
||||
//#define CONFIG_UART_DEADLOCKABLE
|
||||
|
||||
#define SSP_CLK_DIVISOR_FAST 2
|
||||
#define SSP_CLK_DIVISOR_SLOW 250
|
||||
@ -58,20 +59,19 @@
|
||||
#define SSP_CLK_DIVISOR_FPGA_SLOW 20
|
||||
|
||||
#define SNES_RESET_REG LPC_GPIO1
|
||||
#define SNES_RESET_BIT 29
|
||||
/* XXX Rev.B: 1.26 */
|
||||
#define SNES_CIC_D0_REG LPC_GPIO1
|
||||
#define SNES_CIC_D0_BIT 26
|
||||
/* XXX Rev.B: 0.1 */
|
||||
#define SNES_CIC_D1_REG LPC_GPIO1
|
||||
#define SNES_CIC_D1_BIT 25
|
||||
/* XXX Rev.B: 0.0 */
|
||||
#define SNES_CIC_STATUS_REG LPC_GPIO0
|
||||
#define SNES_CIC_STATUS_BIT 1
|
||||
/* XXX Rev.B: 1.29 */
|
||||
#define SNES_CIC_PAIR_REG LPC_GPIO0
|
||||
#define SNES_CIC_PAIR_BIT 0
|
||||
/* XXX Rev.B: 1.25 */
|
||||
#define SNES_RESET_BIT 26
|
||||
|
||||
#define SNES_CIC_D0_REG LPC_GPIO0
|
||||
#define SNES_CIC_D0_BIT 1
|
||||
|
||||
#define SNES_CIC_D1_REG LPC_GPIO0
|
||||
#define SNES_CIC_D1_BIT 0
|
||||
|
||||
#define SNES_CIC_STATUS_REG LPC_GPIO1
|
||||
#define SNES_CIC_STATUS_BIT 29
|
||||
|
||||
#define SNES_CIC_PAIR_REG LPC_GPIO1
|
||||
#define SNES_CIC_PAIR_BIT 25
|
||||
|
||||
#define QSORT_MAXELEM 1024
|
||||
|
||||
@ -88,20 +88,18 @@
|
||||
|
||||
#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_DAT0REG LPC_GPIO2
|
||||
#define SD_DAT1REG LPC_GPIO2
|
||||
#define SD_DAT2REG LPC_GPIO2
|
||||
#define SD_DAT3REG LPC_GPIO2
|
||||
|
||||
#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_DAT0PIN (0)
|
||||
#define SD_DAT1PIN (1)
|
||||
#define SD_DAT2PIN (2)
|
||||
#define SD_DAT3PIN (3)
|
||||
|
||||
#define SD_DAT ((BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN))\
|
||||
|((SD_DAT1REG->FIOPIN1 >> 5) & 0x6)\
|
||||
|((BITBAND(SD_DAT3REG->FIOPIN, SD_DAT3PIN)) << 3))
|
||||
#define SD_DAT (LPC_GPIO2->FIOPIN & 0xf)
|
||||
|
||||
#endif
|
||||
|
||||
@ -26,22 +26,6 @@ loop:
|
||||
uxtb r0, r0 // clear top bits of result
|
||||
bx lr // return
|
||||
|
||||
|
||||
/* uint16_t crc_xmodem_block(uint16_t crc, uint8_t *data, uint32_t len) */
|
||||
.global crc_xmodem_block
|
||||
.thumb_func
|
||||
crc_xmodem_block:
|
||||
adr r12, crc_table // load address of crc table
|
||||
blockloop:
|
||||
ldrb.w r3, [r1], #1 // read data byte
|
||||
eor r3, r3, r0, lsr #8 // EOR data byte
|
||||
ldrh r3, [r12, r3, lsl #1] // load value from CRC table
|
||||
eor r0, r3, r0, lsl #8 // update CRC
|
||||
uxth r0, r0 // clear top bits of result
|
||||
subs r2, r2, #1 // decrement length
|
||||
bne blockloop // loop while length > 0
|
||||
bx lr // return
|
||||
|
||||
/* uint16_t crc_xmodem_block(uint16_t crc, uint8_t *data, uint32_t len) */
|
||||
.global crc_xmodem_update
|
||||
.thumb_func
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
|
||||
void HardFault_Handler(void) {
|
||||
DBG_BL printf("HFSR: %lx\n", SCB->HFSR);
|
||||
uart_putc('H');
|
||||
DBG_UART uart_putc('H');
|
||||
while (1) ;
|
||||
}
|
||||
|
||||
|
||||
@ -2183,7 +2183,7 @@ FRESULT f_read (
|
||||
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)); uart_putc('Y');}
|
||||
mem_cpy(rbuff + ((fp->dsect - sect) * SS(fp->fs)), fp->buf, SS(fp->fs)); }
|
||||
#endif
|
||||
#endif
|
||||
rcnt = SS(fp->fs) * cc; /* Number of bytes transferred */
|
||||
|
||||
@ -127,9 +127,9 @@ FLASH_RES flash_file(uint8_t *filename) {
|
||||
DBG_BL printf("firmware image found. file size: %ld\n", file_handle.fsize);
|
||||
DBG_BL printf("reading header...\n");
|
||||
f_read(&file_handle, &file_header, 32, &bytes_read);
|
||||
print_header(&file_header);
|
||||
DBG_BL print_header(&file_header);
|
||||
if(check_flash() || file_header.version != fw_header->version || file_header.version == FW_MAGIC || fw_header->version == FW_MAGIC) {
|
||||
uart_putc('F');
|
||||
DBG_UART uart_putc('F');
|
||||
f_read(&file_handle, file_buf, 0xe0, &bytes_read);
|
||||
for(;;) {
|
||||
bytes_read = file_read();
|
||||
@ -171,7 +171,7 @@ FLASH_RES flash_file(uint8_t *filename) {
|
||||
current_sec = flash_addr & 0x10000 ? (16 + ((flash_addr >> 15) & 1))
|
||||
: (flash_addr >> 12);
|
||||
DBG_BL printf("current_sec=%d flash_addr=%08lx\n", current_sec, flash_addr);
|
||||
uart_putc('.');
|
||||
DBG_UART uart_putc('.');
|
||||
toggle_rdy_led();
|
||||
if(current_sec < (FW_START / 0x1000)) return ERR_FLASH;
|
||||
if((res = iap_prepare_for_write(current_sec, current_sec)) != CMD_SUCCESS) {
|
||||
@ -185,11 +185,11 @@ FLASH_RES flash_file(uint8_t *filename) {
|
||||
}
|
||||
if(total_read != file_header.size) {
|
||||
DBG_BL printf("wrote less data than expected! (%08lx vs. %08lx)\n", total_read, file_header.size);
|
||||
uart_putc('X');
|
||||
DBG_UART uart_putc('X');
|
||||
return ERR_FILECHK;
|
||||
}
|
||||
} else {
|
||||
uart_putc('n');
|
||||
DBG_UART uart_putc('n');
|
||||
DBG_BL printf("flash content is ok, no version mismatch, no forced upgrade. No need to flash\n");
|
||||
}
|
||||
return ERR_OK;
|
||||
|
||||
@ -9,18 +9,27 @@ int led_rdyledstate = 0;
|
||||
int led_readledstate = 0;
|
||||
int led_writeledstate = 0;
|
||||
|
||||
/* LED connections (Rev.C)
|
||||
|
||||
LED color IO PWM
|
||||
---------------------------
|
||||
ready green P2.4 PWM1[5]
|
||||
read yellow P2.5 PWM1[6]
|
||||
write red P1.23 PWM1[4]
|
||||
*/
|
||||
|
||||
void rdyled(unsigned int state) {
|
||||
BITBAND(LPC_GPIO2->FIODIR, 0) = state;
|
||||
BITBAND(LPC_GPIO2->FIODIR, 4) = state;
|
||||
led_rdyledstate = state;
|
||||
}
|
||||
|
||||
void readled(unsigned int state) {
|
||||
BITBAND(LPC_GPIO2->FIODIR, 1) = state;
|
||||
BITBAND(LPC_GPIO2->FIODIR, 5) = state;
|
||||
led_readledstate = state;
|
||||
}
|
||||
|
||||
void writeled(unsigned int state) {
|
||||
BITBAND(LPC_GPIO2->FIODIR, 2) = state;
|
||||
BITBAND(LPC_GPIO1->FIODIR, 23) = state;
|
||||
led_writeledstate = state;
|
||||
}
|
||||
|
||||
@ -36,7 +45,7 @@ void led_clkout32(uint32_t val) {
|
||||
}
|
||||
|
||||
void toggle_rdy_led() {
|
||||
rdyled(!led_rdyledstate);
|
||||
rdyled(~led_rdyledstate);
|
||||
}
|
||||
|
||||
void toggle_read_led() {
|
||||
@ -49,21 +58,28 @@ void toggle_write_led() {
|
||||
|
||||
void led_panic() {
|
||||
while(1) {
|
||||
LPC_GPIO2->FIODIR |= BV(0) | BV(1) | BV(2);
|
||||
LPC_GPIO2->FIODIR |= BV(4) | BV(5);
|
||||
LPC_GPIO1->FIODIR |= BV(23);
|
||||
delay_ms(350);
|
||||
LPC_GPIO2->FIODIR &= ~(BV(0) | BV(1) | BV(2));
|
||||
LPC_GPIO2->FIODIR &= ~(BV(4) | BV(5));
|
||||
LPC_GPIO1->FIODIR &= ~BV(23);
|
||||
delay_ms(350);
|
||||
}
|
||||
}
|
||||
|
||||
void led_std() {
|
||||
BITBAND(LPC_PINCON->PINSEL4, 1) = 0;
|
||||
BITBAND(LPC_PINCON->PINSEL4, 3) = 0;
|
||||
BITBAND(LPC_PINCON->PINSEL4, 5) = 0;
|
||||
BITBAND(LPC_PINCON->PINSEL4, 9) = 0;
|
||||
BITBAND(LPC_PINCON->PINSEL4, 8) = 0;
|
||||
|
||||
BITBAND(LPC_PINCON->PINSEL4, 0) = 0;
|
||||
BITBAND(LPC_PINCON->PINSEL4, 2) = 0;
|
||||
BITBAND(LPC_PINCON->PINSEL4, 4) = 0;
|
||||
BITBAND(LPC_PINCON->PINSEL4, 11) = 0;
|
||||
BITBAND(LPC_PINCON->PINSEL4, 10) = 0;
|
||||
|
||||
BITBAND(LPC_PINCON->PINSEL3, 15) = 0;
|
||||
BITBAND(LPC_PINCON->PINSEL3, 14) = 0;
|
||||
|
||||
BITBAND(LPC_PWM1->PCR, 12) = 0;
|
||||
BITBAND(LPC_PWM1->PCR, 13) = 0;
|
||||
BITBAND(LPC_PWM1->PCR, 14) = 0;
|
||||
}
|
||||
|
||||
void led_init() {
|
||||
|
||||
@ -10,7 +10,7 @@ ENTRY(_start)
|
||||
|
||||
MEMORY
|
||||
{
|
||||
flash (rx) : ORIGIN = 0x00000000, LENGTH = 0x03000
|
||||
flash (rx) : ORIGIN = 0x00000000, LENGTH = 0x02000
|
||||
ram (rwx) : ORIGIN = 0x10000000, LENGTH = 0x03fe0 /* leave room for IAP */
|
||||
ahbram (rwx) : ORIGIN = 0x2007C000, LENGTH = 0x04000
|
||||
}
|
||||
|
||||
@ -42,7 +42,7 @@ int main(void) {
|
||||
clock_disconnect();
|
||||
power_init();
|
||||
timer_init();
|
||||
uart_init();
|
||||
DBG_UART uart_init();
|
||||
led_init();
|
||||
readled(0);
|
||||
rdyled(0);
|
||||
|
||||
@ -66,12 +66,13 @@
|
||||
#define CARD_SDHC (1<<1)
|
||||
|
||||
/*
|
||||
1 DAT3/SS P0.6
|
||||
2 CMD/DI P0.9
|
||||
5 Clock P0.7
|
||||
7 DAT0/DO P0.8
|
||||
8 DAT1/IRQ P1.14
|
||||
9 DAT2/NC P1.15
|
||||
Rev.A Rev.C
|
||||
1 DAT3/SS P0.6 P2.3
|
||||
2 CMD/DI P0.9 P0.9
|
||||
5 Clock P0.7 P0.7
|
||||
7 DAT0/DO P0.8 P2.0
|
||||
8 DAT1/IRQ P1.14 P2.1
|
||||
9 DAT2/NC P1.15 P2.2
|
||||
*/
|
||||
|
||||
/* SD init procedure
|
||||
@ -195,6 +196,42 @@ static inline void wiggle_fast_pos1(void) {
|
||||
BITBAND(SD_CLKREG->FIOCLR, SD_CLKPIN) = 1;
|
||||
}
|
||||
|
||||
int get_and_check_datacrc(uint8_t *buf) {
|
||||
uint16_t crc0=0, crc1=0, crc2=0, crc3=0;
|
||||
uint16_t sdcrc0=0, sdcrc1=0, sdcrc2=0, sdcrc3=0;
|
||||
uint8_t d0=0, d1=0, d2=0, d3=0;
|
||||
uint8_t datdata;
|
||||
uint16_t datcnt;
|
||||
/* get crcs from card */
|
||||
for (datcnt=0; datcnt < 16; datcnt++) {
|
||||
datdata = SD_DAT;
|
||||
wiggle_fast_neg1();
|
||||
sdcrc0 = ((sdcrc0 << 1) & 0xfffe) | ((datdata >> 3) & 0x0001);
|
||||
sdcrc1 = ((sdcrc1 << 1) & 0xfffe) | ((datdata >> 2) & 0x0001);
|
||||
sdcrc2 = ((sdcrc2 << 1) & 0xfffe) | ((datdata >> 1) & 0x0001);
|
||||
sdcrc3 = ((sdcrc3 << 1) & 0xfffe) | ((datdata >> 0) & 0x0001);
|
||||
}
|
||||
wiggle_fast_neg1();
|
||||
/* calc crcs from data */
|
||||
for (datcnt=0; datcnt < 512; datcnt++) {
|
||||
d0 = ((d0 << 2) & 0xfc) | ((buf[datcnt] >> 6) & 0x02) | ((buf[datcnt] >> 3) & 0x01) ;
|
||||
d1 = ((d1 << 2) & 0xfc) | ((buf[datcnt] >> 5) & 0x02) | ((buf[datcnt] >> 2) & 0x01) ;
|
||||
d2 = ((d2 << 2) & 0xfc) | ((buf[datcnt] >> 4) & 0x02) | ((buf[datcnt] >> 1) & 0x01) ;
|
||||
d3 = ((d3 << 2) & 0xfc) | ((buf[datcnt] >> 3) & 0x02) | ((buf[datcnt] >> 0) & 0x01) ;
|
||||
if((datcnt % 4) == 3) {
|
||||
crc0 = crc_xmodem_update(crc0, d0);
|
||||
crc1 = crc_xmodem_update(crc1, d1);
|
||||
crc2 = crc_xmodem_update(crc2, d2);
|
||||
crc3 = crc_xmodem_update(crc3, d3);
|
||||
}
|
||||
}
|
||||
if((crc0 != sdcrc0) || (crc1 != sdcrc1) || (crc2 != sdcrc2) || (crc3 != sdcrc3)) {
|
||||
DBG_SD printf("CRC mismatch\nSDCRC CRC\n %04x %04x\n %04x %04x\n %04x %04x\n %04x %04x\n", sdcrc0, crc0, sdcrc1, crc1, sdcrc2, crc2, sdcrc3, crc3);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void wait_busy(void) {
|
||||
while(!(BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN))) {
|
||||
wiggle_fast_neg1();
|
||||
@ -446,8 +483,16 @@ int send_command_fast(uint8_t* cmd, uint8_t* rsp, uint8_t* buf){
|
||||
}
|
||||
}
|
||||
}
|
||||
/* just eat the crcs for now */
|
||||
if(dat) wiggle_fast_neg(17);
|
||||
if(dat) {
|
||||
#ifdef CONFIG_SD_DATACRC
|
||||
if(get_and_check_datacrc(buf-512)) {
|
||||
return CRC_ERROR;
|
||||
}
|
||||
#else
|
||||
/* eat the crcs */
|
||||
wiggle_fast_neg(17);
|
||||
#endif
|
||||
}
|
||||
|
||||
if(waitbusy) {
|
||||
DBG_SD printf("waitbusy after send_cmd\n");
|
||||
@ -515,7 +560,7 @@ int acmd_fast(uint8_t cmd, uint32_t param, uint8_t crc, uint8_t* dat, uint8_t* r
|
||||
return cmd_fast(cmd, param, crc, dat, rsp);
|
||||
}
|
||||
|
||||
void stream_datablock(uint8_t *buf) {
|
||||
int stream_datablock(uint8_t *buf) {
|
||||
// uint8_t datshift=8;
|
||||
int j=512;
|
||||
uint8_t datdata=0;
|
||||
@ -537,8 +582,13 @@ void stream_datablock(uint8_t *buf) {
|
||||
j--;
|
||||
if(!j) break;
|
||||
}
|
||||
/* eat the crc for now */
|
||||
#ifdef CONFIG_SD_DATACRC
|
||||
return get_and_check_datacrc(buf-512);
|
||||
#else
|
||||
/* eat the crcs */
|
||||
wiggle_fast_neg(17);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
void send_datablock(uint8_t *buf) {
|
||||
@ -667,7 +717,17 @@ void send_datablock(uint8_t *buf) {
|
||||
void read_block(uint32_t address, uint8_t *buf) {
|
||||
if(during_blocktrans == TRANS_READ && (last_block == address-1)) {
|
||||
//uart_putc('r');
|
||||
#ifdef CONFIG_SD_DATACRC
|
||||
int cmd_res;
|
||||
if((cmd_res = stream_datablock(buf)) == CRC_ERROR) {
|
||||
while(cmd_res == CRC_ERROR) {
|
||||
cmd_fast(STOP_TRANSMISSION, 0, 0x61, NULL, rsp);
|
||||
cmd_res = cmd_fast(READ_MULTIPLE_BLOCK, address, 0, buf, rsp);
|
||||
}
|
||||
}
|
||||
#else
|
||||
stream_datablock(buf);
|
||||
#endif
|
||||
last_block=address;
|
||||
} else {
|
||||
if(during_blocktrans) {
|
||||
@ -680,7 +740,14 @@ void read_block(uint32_t address, uint8_t *buf) {
|
||||
if(!ccs) {
|
||||
address <<= 9;
|
||||
}
|
||||
#ifdef CONFIG_SD_DATACRC
|
||||
while(1) {
|
||||
if(cmd_fast(READ_MULTIPLE_BLOCK, address, 0, buf, rsp) != CRC_ERROR) break;
|
||||
cmd_fast(STOP_TRANSMISSION, 0, 0x61, NULL, rsp);
|
||||
};
|
||||
#else
|
||||
cmd_fast(READ_MULTIPLE_BLOCK, address, 0, buf, rsp);
|
||||
#endif
|
||||
during_blocktrans = TRANS_READ;
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,6 +11,8 @@
|
||||
|
||||
#include "diskio.h"
|
||||
|
||||
#define CRC_ERROR (0xf000)
|
||||
|
||||
/* These functions are weak-aliased to disk_... */
|
||||
void sdn_init(void);
|
||||
DSTATUS sdn_status(BYTE drv);
|
||||
|
||||
4635
src/cfgware.h
4635
src/cfgware.h
File diff suppressed because it is too large
Load Diff
@ -388,7 +388,7 @@ void cmd_settime(void) {
|
||||
curchar[4+2] = 0;
|
||||
time.tm_mon = atoi(curchar+4);
|
||||
curchar[4] = 0;
|
||||
time.tm_year = atoi(curchar) - 1900;
|
||||
time.tm_year = atoi(curchar);
|
||||
set_rtc(&time);
|
||||
}
|
||||
}
|
||||
@ -396,7 +396,7 @@ void cmd_settime(void) {
|
||||
void cmd_time(void) {
|
||||
struct tm time;
|
||||
read_rtc(&time);
|
||||
printf("%04d-%02d-%02d %02d:%02d:%02d\n", time.tm_year+1900, time.tm_mon,
|
||||
printf("%04d-%02d-%02d %02d:%02d:%02d\n", time.tm_year, time.tm_mon,
|
||||
time.tm_mday, time.tm_hour, time.tm_min, time.tm_sec);
|
||||
}
|
||||
|
||||
@ -513,6 +513,11 @@ void cli_loop(void) {
|
||||
case CMD_TIME:
|
||||
cmd_time();
|
||||
break;
|
||||
|
||||
case CMD_TEST:
|
||||
testbattery();
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -49,7 +49,8 @@ void clock_init() {
|
||||
enableMainOsc();
|
||||
setClkSrc(CLKSRC_MAINOSC);
|
||||
// XXX setPLL0MultPrediv(429, 19);
|
||||
setPLL0MultPrediv(23, 2);
|
||||
// XXX setPLL0MultPrediv(23, 2);
|
||||
setPLL0MultPrediv(12, 1);
|
||||
enablePLL0();
|
||||
setCCLKDiv(3);
|
||||
connectPLL0();
|
||||
|
||||
61
src/config.h
61
src/config.h
@ -18,10 +18,10 @@
|
||||
|
||||
#define SD_CHANGE_CLR() do {LPC_GPIOINT->IO2IntClr = BV(SD_DT_BIT);} while(0)
|
||||
|
||||
#define SD_DT_REG LPC_GPIO2
|
||||
#define SD_DT_BIT 3
|
||||
#define SD_WP_REG LPC_GPIO2
|
||||
#define SD_WP_BIT 4
|
||||
#define SD_DT_REG LPC_GPIO0
|
||||
#define SD_DT_BIT 8
|
||||
#define SD_WP_REG LPC_GPIO0
|
||||
#define SD_WP_BIT 6
|
||||
|
||||
#define SDCARD_DETECT (!(BITBAND(SD_DT_REG->FIOPIN, SD_DT_BIT)))
|
||||
#define SDCARD_WP (BITBAND(SD_WP_REG->FIOPIN, SD_WP_BIT))
|
||||
@ -33,12 +33,12 @@
|
||||
|
||||
#define CONFIG_UART_NUM 3
|
||||
// #define CONFIG_CPU_FREQUENCY 90315789
|
||||
#define CONFIG_CPU_FREQUENCY 92000000
|
||||
#define CONFIG_CPU_FREQUENCY 96000000
|
||||
//#define CONFIG_CPU_FREQUENCY 46000000
|
||||
#define CONFIG_UART_PCLKDIV 1
|
||||
#define CONFIG_UART_TX_BUF_SHIFT 10
|
||||
#define CONFIG_UART_TX_BUF_SHIFT 8
|
||||
#define CONFIG_UART_BAUDRATE 921600
|
||||
//#define CONFIG_UART_DEADLOCKABLE
|
||||
#define CONFIG_UART_DEADLOCKABLE
|
||||
|
||||
#define SSP_CLK_DIVISOR_FAST 2
|
||||
#define SSP_CLK_DIVISOR_SLOW 250
|
||||
@ -47,20 +47,19 @@
|
||||
#define SSP_CLK_DIVISOR_FPGA_SLOW 20
|
||||
|
||||
#define SNES_RESET_REG LPC_GPIO1
|
||||
#define SNES_RESET_BIT 29
|
||||
/* XXX Rev.B: 1.26 */
|
||||
#define SNES_CIC_D0_REG LPC_GPIO1
|
||||
#define SNES_CIC_D0_BIT 26
|
||||
/* XXX Rev.B: 0.1 */
|
||||
#define SNES_CIC_D1_REG LPC_GPIO1
|
||||
#define SNES_CIC_D1_BIT 25
|
||||
/* XXX Rev.B: 0.0 */
|
||||
#define SNES_CIC_STATUS_REG LPC_GPIO0
|
||||
#define SNES_CIC_STATUS_BIT 1
|
||||
/* XXX Rev.B: 1.29 */
|
||||
#define SNES_CIC_PAIR_REG LPC_GPIO0
|
||||
#define SNES_CIC_PAIR_BIT 0
|
||||
/* XXX Rev.B: 1.25 */
|
||||
#define SNES_RESET_BIT 26
|
||||
|
||||
#define SNES_CIC_D0_REG LPC_GPIO0
|
||||
#define SNES_CIC_D0_BIT 1
|
||||
|
||||
#define SNES_CIC_D1_REG LPC_GPIO0
|
||||
#define SNES_CIC_D1_BIT 0
|
||||
|
||||
#define SNES_CIC_STATUS_REG LPC_GPIO1
|
||||
#define SNES_CIC_STATUS_BIT 29
|
||||
|
||||
#define SNES_CIC_PAIR_REG LPC_GPIO1
|
||||
#define SNES_CIC_PAIR_BIT 25
|
||||
|
||||
#define QSORT_MAXELEM 1024
|
||||
|
||||
@ -77,20 +76,18 @@
|
||||
|
||||
#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_DAT0REG LPC_GPIO2
|
||||
#define SD_DAT1REG LPC_GPIO2
|
||||
#define SD_DAT2REG LPC_GPIO2
|
||||
#define SD_DAT3REG LPC_GPIO2
|
||||
|
||||
#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_DAT0PIN (0)
|
||||
#define SD_DAT1PIN (1)
|
||||
#define SD_DAT2PIN (2)
|
||||
#define SD_DAT3PIN (3)
|
||||
|
||||
#define SD_DAT ((BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN))\
|
||||
|((SD_DAT1REG->FIOPIN1 >> 5) & 0x6)\
|
||||
|((BITBAND(SD_DAT3REG->FIOPIN, SD_DAT3PIN)) << 3))
|
||||
#define SD_DAT (LPC_GPIO2->FIOPIN0)
|
||||
|
||||
#endif
|
||||
|
||||
11
src/crc16.c
11
src/crc16.c
@ -20,7 +20,7 @@
|
||||
/**
|
||||
* Static table used for the table_driven implementation.
|
||||
*****************************************************************************/
|
||||
static const crc_t crc_table[256] = {
|
||||
static const uint16_t crc_table[256] = {
|
||||
0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241,
|
||||
0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440,
|
||||
0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40,
|
||||
@ -63,14 +63,11 @@ static const crc_t crc_table[256] = {
|
||||
* \param data_len Number of bytes in the \a data buffer.
|
||||
* \return The updated crc value.
|
||||
*****************************************************************************/
|
||||
crc_t crc16_update(crc_t crc, const unsigned char *data, size_t data_len)
|
||||
uint16_t crc16_update(uint16_t crc, const unsigned char data)
|
||||
{
|
||||
unsigned int tbl_idx;
|
||||
while (data_len--) {
|
||||
tbl_idx = (crc ^ *data) & 0xff;
|
||||
crc = (crc_table[tbl_idx] ^ (crc >> 8)) & 0xffff;
|
||||
data++;
|
||||
}
|
||||
tbl_idx = (crc ^ data) & 0xff;
|
||||
crc = (crc_table[tbl_idx] ^ (crc >> 8)) & 0xffff;
|
||||
return crc & 0xffff;
|
||||
}
|
||||
|
||||
|
||||
@ -29,13 +29,6 @@ extern "C" {
|
||||
*****************************************************************************/
|
||||
#define CRC_ALGO_BIT_BY_BIT_FAST 1
|
||||
|
||||
/**
|
||||
* The type of the CRC values.
|
||||
*
|
||||
* This type must be big enough to contain at least 16 bits.
|
||||
*****************************************************************************/
|
||||
typedef uint16_t crc_t;
|
||||
|
||||
/**
|
||||
* Update the crc value with new data.
|
||||
*
|
||||
@ -44,7 +37,7 @@ typedef uint16_t crc_t;
|
||||
* \param data_len Number of bytes in the \a data buffer.
|
||||
* \return The updated crc value.
|
||||
*****************************************************************************/
|
||||
crc_t crc16_update(crc_t crc, const unsigned char *data, size_t data_len);
|
||||
uint16_t crc16_update(uint16_t crc, const unsigned char data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* closing brace for extern "C" */
|
||||
|
||||
@ -84,7 +84,7 @@ uint32_t scan_dir(char* path, char mkdb, uint32_t this_dir_tgt) {
|
||||
this_dir_tgt = SRAM_DIR_ADDR;
|
||||
parent_tgt = 0;
|
||||
printf("root dir @%lx\n", dir_tgt);
|
||||
}
|
||||
}
|
||||
|
||||
fno.lfsize = 255;
|
||||
fno.lfname = (TCHAR*)file_lfn;
|
||||
@ -178,6 +178,7 @@ uint32_t scan_dir(char* path, char mkdb, uint32_t this_dir_tgt) {
|
||||
strncpy(path+len+1, (char*)fn, sizeof(fs_path)-len);
|
||||
uint16_t pathlen = strlen(path);
|
||||
switch(type) {
|
||||
case TYPE_IPS:
|
||||
case TYPE_SMC:
|
||||
/* file_open_by_filinfo(&fno);
|
||||
if(file_res){
|
||||
@ -194,7 +195,7 @@ uint32_t scan_dir(char* path, char mkdb, uint32_t this_dir_tgt) {
|
||||
db_tgt += 0x00010000;
|
||||
printf("new=%lx\n", db_tgt);
|
||||
}
|
||||
sram_writelong((db_tgt-SRAM_MENU_ADDR), dir_tgt);
|
||||
sram_writelong((db_tgt-SRAM_MENU_ADDR) | ((uint32_t)type << 24), dir_tgt);
|
||||
dir_tgt += 4;
|
||||
/* save element:
|
||||
- index of last slash character
|
||||
@ -252,7 +253,13 @@ SNES_FTYPE determine_filetype(char* filename) {
|
||||
||(!strcasecmp(ext+1, "FIG"))
|
||||
) {
|
||||
return TYPE_SMC;
|
||||
}/* later
|
||||
}
|
||||
if( (!strcasecmp(ext+1, "IPS"))
|
||||
||(!strcasecmp(ext+1, "UPS"))
|
||||
) {
|
||||
return TYPE_IPS;
|
||||
}
|
||||
/* later
|
||||
if(!strcasecmp_P(ext+1, PSTR("SRM"))) {
|
||||
return TYPE_SRM;
|
||||
}
|
||||
|
||||
@ -29,10 +29,11 @@
|
||||
|
||||
#include "ff.h"
|
||||
typedef enum {
|
||||
TYPE_UNKNOWN = 0, /* 0 */
|
||||
TYPE_SMC, /* 1 */
|
||||
TYPE_SRM, /* 2 */
|
||||
TYPE_SPC /* 3 */
|
||||
TYPE_UNKNOWN = 0, /* 0 */
|
||||
TYPE_SMC, /* 1 */
|
||||
TYPE_SRM, /* 2 */
|
||||
TYPE_SPC, /* 3 */
|
||||
TYPE_IPS /* 4 */
|
||||
} SNES_FTYPE;
|
||||
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
#flash info 0
|
||||
|
||||
reset init
|
||||
flash write_image erase unlock obj/sd2snes.elf
|
||||
flash write_image erase unlock obj/firmware.img 8192
|
||||
reset run
|
||||
shutdown
|
||||
|
||||
|
||||
@ -53,10 +53,10 @@
|
||||
|
||||
8p - read (RAM only)
|
||||
p: 0 = no increment after read
|
||||
1 = increment after read
|
||||
8 = increment after read
|
||||
|
||||
9p {xx}* write xx
|
||||
p: tt-i
|
||||
p: i-tt
|
||||
tt = target (see above)
|
||||
i = increment (see above)
|
||||
|
||||
@ -73,6 +73,7 @@
|
||||
nibbles packed)
|
||||
eg 0x20111210094816 is 2011-12-10, 9:48:16
|
||||
E6 ssrr set/reset BS-X status register [7:0]
|
||||
E7 - reset SRTC state
|
||||
F0 - receive test token (to see if FPGA is alive)
|
||||
F1 - receive status (16bit, MSB first), see below
|
||||
|
||||
@ -336,3 +337,11 @@ void set_fpga_time(uint64_t time) {
|
||||
FPGA_TX_BYTE(0x00);
|
||||
FPGA_DESELECT();
|
||||
}
|
||||
|
||||
void fpga_reset_srtc_state() {
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0xe7);
|
||||
FPGA_TX_BYTE(0x00);
|
||||
FPGA_TX_BYTE(0x00);
|
||||
FPGA_DESELECT();
|
||||
}
|
||||
|
||||
@ -74,5 +74,6 @@ uint32_t get_msu_offset(void);
|
||||
uint32_t get_snes_sysclk(void);
|
||||
void set_bsx_regs(uint8_t set, uint8_t reset);
|
||||
void set_fpga_time(uint64_t time);
|
||||
void fpga_reset_srtc_state(void);
|
||||
|
||||
#endif
|
||||
|
||||
74
src/led.c
74
src/led.c
@ -12,11 +12,20 @@ int led_readledstate = 0;
|
||||
int led_writeledstate = 0;
|
||||
int led_pwmstate = 0;
|
||||
|
||||
/* LED connections (Rev.C)
|
||||
|
||||
LED color IO PWM
|
||||
---------------------------
|
||||
ready green P2.4 PWM1[5]
|
||||
read yellow P2.5 PWM1[6]
|
||||
write red P1.23 PWM1[4]
|
||||
*/
|
||||
|
||||
void rdyled(unsigned int state) {
|
||||
if(led_pwmstate) {
|
||||
rdybright(state?15:0);
|
||||
} else {
|
||||
BITBAND(LPC_GPIO2->FIODIR, 0) = state;
|
||||
BITBAND(LPC_GPIO2->FIODIR, 4) = state;
|
||||
}
|
||||
led_rdyledstate = state;
|
||||
}
|
||||
@ -25,7 +34,7 @@ void readled(unsigned int state) {
|
||||
if(led_pwmstate) {
|
||||
readbright(state?15:0);
|
||||
} else {
|
||||
BITBAND(LPC_GPIO2->FIODIR, 1) = state;
|
||||
BITBAND(LPC_GPIO2->FIODIR, 5) = state;
|
||||
}
|
||||
led_readledstate = state;
|
||||
}
|
||||
@ -34,22 +43,22 @@ void writeled(unsigned int state) {
|
||||
if(led_pwmstate) {
|
||||
writebright(state?15:0);
|
||||
} else {
|
||||
BITBAND(LPC_GPIO2->FIODIR, 2) = state;
|
||||
BITBAND(LPC_GPIO1->FIODIR, 23) = state;
|
||||
}
|
||||
led_writeledstate = state;
|
||||
}
|
||||
|
||||
void rdybright(uint8_t bright) {
|
||||
LPC_PWM1->MR1 = led_bright[(bright & 15)];
|
||||
BITBAND(LPC_PWM1->LER, 1) = 1;
|
||||
LPC_PWM1->MR5 = led_bright[(bright & 15)];
|
||||
BITBAND(LPC_PWM1->LER, 5) = 1;
|
||||
}
|
||||
void readbright(uint8_t bright) {
|
||||
LPC_PWM1->MR2 = led_bright[(bright & 15)];
|
||||
BITBAND(LPC_PWM1->LER, 2) = 1;
|
||||
LPC_PWM1->MR6 = led_bright[(bright & 15)];
|
||||
BITBAND(LPC_PWM1->LER, 6) = 1;
|
||||
}
|
||||
void writebright(uint8_t bright) {
|
||||
LPC_PWM1->MR3 = led_bright[(bright & 15)];
|
||||
BITBAND(LPC_PWM1->LER, 3) = 1;
|
||||
LPC_PWM1->MR4 = led_bright[(bright & 15)];
|
||||
BITBAND(LPC_PWM1->LER, 4) = 1;
|
||||
}
|
||||
|
||||
void led_clkout32(uint32_t val) {
|
||||
@ -77,43 +86,46 @@ void toggle_write_led() {
|
||||
|
||||
void led_panic() {
|
||||
while(1) {
|
||||
LPC_GPIO2->FIODIR |= BV(0) | BV(1) | BV(2);
|
||||
LPC_GPIO2->FIODIR |= BV(4) | BV(5);
|
||||
LPC_GPIO1->FIODIR |= BV(23);
|
||||
delay_ms(350);
|
||||
LPC_GPIO2->FIODIR &= ~(BV(0) | BV(1) | BV(2));
|
||||
LPC_GPIO2->FIODIR &= ~(BV(4) | BV(5));
|
||||
LPC_GPIO1->FIODIR &= ~BV(23);
|
||||
delay_ms(350);
|
||||
}
|
||||
}
|
||||
|
||||
void led_pwm() {
|
||||
/* connect PWM to P2.0 - P2.2 */
|
||||
/* XXX Rev.B P2.???? */
|
||||
BITBAND(LPC_PINCON->PINSEL4, 1) = 0;
|
||||
BITBAND(LPC_PINCON->PINSEL4, 3) = 0;
|
||||
BITBAND(LPC_PINCON->PINSEL4, 5) = 0;
|
||||
/* Rev.C P2.4, P2.5, P1.23 */
|
||||
BITBAND(LPC_PINCON->PINSEL4, 9) = 0;
|
||||
BITBAND(LPC_PINCON->PINSEL4, 8) = 1;
|
||||
|
||||
BITBAND(LPC_PINCON->PINSEL4, 0) = 1;
|
||||
BITBAND(LPC_PINCON->PINSEL4, 2) = 1;
|
||||
BITBAND(LPC_PINCON->PINSEL4, 4) = 1;
|
||||
BITBAND(LPC_PINCON->PINSEL4, 11) = 0;
|
||||
BITBAND(LPC_PINCON->PINSEL4, 10) = 1;
|
||||
|
||||
BITBAND(LPC_PWM1->PCR, 9) = 1;
|
||||
BITBAND(LPC_PWM1->PCR, 10) = 1;
|
||||
BITBAND(LPC_PWM1->PCR, 11) = 1;
|
||||
BITBAND(LPC_PINCON->PINSEL3, 15) = 1;
|
||||
BITBAND(LPC_PINCON->PINSEL3, 14) = 0;
|
||||
|
||||
BITBAND(LPC_PWM1->PCR, 12) = 1;
|
||||
BITBAND(LPC_PWM1->PCR, 13) = 1;
|
||||
BITBAND(LPC_PWM1->PCR, 14) = 1;
|
||||
|
||||
led_pwmstate = 1;
|
||||
}
|
||||
|
||||
void led_std() {
|
||||
BITBAND(LPC_PINCON->PINSEL4, 1) = 0;
|
||||
BITBAND(LPC_PINCON->PINSEL4, 3) = 0;
|
||||
BITBAND(LPC_PINCON->PINSEL4, 5) = 0;
|
||||
BITBAND(LPC_PINCON->PINSEL4, 9) = 0;
|
||||
BITBAND(LPC_PINCON->PINSEL4, 8) = 0;
|
||||
|
||||
BITBAND(LPC_PINCON->PINSEL4, 0) = 0;
|
||||
BITBAND(LPC_PINCON->PINSEL4, 2) = 0;
|
||||
BITBAND(LPC_PINCON->PINSEL4, 4) = 0;
|
||||
BITBAND(LPC_PINCON->PINSEL4, 11) = 0;
|
||||
BITBAND(LPC_PINCON->PINSEL4, 10) = 0;
|
||||
|
||||
BITBAND(LPC_PWM1->PCR, 9) = 0;
|
||||
BITBAND(LPC_PWM1->PCR, 10) = 0;
|
||||
BITBAND(LPC_PWM1->PCR, 11) = 0;
|
||||
BITBAND(LPC_PINCON->PINSEL3, 15) = 0;
|
||||
BITBAND(LPC_PINCON->PINSEL3, 14) = 0;
|
||||
|
||||
BITBAND(LPC_PWM1->PCR, 12) = 0;
|
||||
BITBAND(LPC_PWM1->PCR, 13) = 0;
|
||||
BITBAND(LPC_PWM1->PCR, 14) = 0;
|
||||
|
||||
led_pwmstate = 0;
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@ ENTRY(_start)
|
||||
|
||||
MEMORY
|
||||
{
|
||||
flash (rx) : ORIGIN = 0x00004100, LENGTH = 0x1bf00 /* leave room for bootldr + metadata */
|
||||
flash (rx) : ORIGIN = 0x00002100, LENGTH = 0x1df00 /* leave room for bootldr + metadata */
|
||||
ram (rwx) : ORIGIN = 0x10000000, LENGTH = 0x04000
|
||||
ahbram (rwx) : ORIGIN = 0x2007C000, LENGTH = 0x04000
|
||||
}
|
||||
|
||||
48
src/main.c
48
src/main.c
@ -25,8 +25,8 @@
|
||||
#include "crc.h"
|
||||
#include "smc.h"
|
||||
#include "msu1.h"
|
||||
#include "rtc.h"
|
||||
|
||||
#include "usb_hid.h"
|
||||
#define EMC0TOGGLE (3<<4)
|
||||
#define MR0R (1<<1)
|
||||
|
||||
@ -37,14 +37,18 @@ 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;
|
||||
extern snes_romprops_t romprops;
|
||||
extern volatile int reset_changed;
|
||||
|
||||
enum system_states {
|
||||
SYS_RTC_STATUS = 0
|
||||
};
|
||||
|
||||
int main(void) {
|
||||
LPC_GPIO2->FIODIR = BV(0) | BV(1) | BV(2);
|
||||
LPC_GPIO1->FIODIR = 0;
|
||||
LPC_GPIO2->FIODIR = BV(4) | BV(5);
|
||||
LPC_GPIO1->FIODIR = BV(23);
|
||||
LPC_GPIO0->FIODIR = BV(16);
|
||||
|
||||
/* connect UART3 on P0[25:26] + SSP0 on P0[15:18] + MAT3.0 on P0[10] */
|
||||
@ -54,7 +58,7 @@ int main(void) {
|
||||
/* | BV(13) | BV(15) | BV(17) | BV(19) SSP1 (SD) */
|
||||
|
||||
/* pull-down CIC data lines */
|
||||
LPC_PINCON->PINMODE3 = BV(18) | BV(19) | BV(20) | BV(21);
|
||||
LPC_PINCON->PINMODE0 = BV(0) | BV(1) | BV(2) | BV(3);
|
||||
|
||||
clock_disconnect();
|
||||
snes_init();
|
||||
@ -72,6 +76,7 @@ led_pwm();
|
||||
sdn_init();
|
||||
printf("\n\nsd2snes mk.2\n============\nfw ver.: " VER "\ncpu clock: %d Hz\n", CONFIG_CPU_FREQUENCY);
|
||||
printf("PCONP=%lx\n", LPC_SC->PCONP);
|
||||
|
||||
file_init();
|
||||
cic_init(0);
|
||||
/* setup timer (fpga clk) */
|
||||
@ -197,22 +202,35 @@ printf("PCONP=%lx\n", LPC_SC->PCONP);
|
||||
/* shared mode */
|
||||
set_mcu_ovr(0);
|
||||
|
||||
if((rtc_state = rtc_isvalid()) != RTC_OK) {
|
||||
printf("RTC invalid!\n");
|
||||
sram_writebyte(0xff, SRAM_STATUS_ADDR+SYS_RTC_STATUS);
|
||||
set_bcdtime(0x20110401000000LL);
|
||||
set_fpga_time(0x20110401000000LL);
|
||||
invalidate_rtc();
|
||||
} else {
|
||||
printf("RTC valid!\n");
|
||||
sram_writebyte(0x00, SRAM_STATUS_ADDR+SYS_RTC_STATUS);
|
||||
set_fpga_time(get_bcdtime());
|
||||
}
|
||||
|
||||
printf("SNES GO!\n");
|
||||
snes_reset(1);
|
||||
delay_ms(1);
|
||||
snes_reset(0);
|
||||
|
||||
uint8_t cmd = 0;
|
||||
uint64_t btime = 0;
|
||||
uint32_t filesize=0;
|
||||
sram_writebyte(32, SRAM_CMD_ADDR);
|
||||
printf("test sram\n");
|
||||
while(!sram_reliable());
|
||||
printf("ok\n");
|
||||
|
||||
//while(1) {
|
||||
// delay_ms(1000);
|
||||
// printf("Estimated SNES master clock: %ld Hz\n", get_snes_sysclk());
|
||||
//}
|
||||
sram_hexdump(SRAM_DIR_ADDR, 0x300);
|
||||
//while(1) {
|
||||
// delay_ms(1000);
|
||||
// printf("Estimated SNES master clock: %ld Hz\n", get_snes_sysclk());
|
||||
//}
|
||||
//sram_hexdump(SRAM_DB_ADDR, 0x200);
|
||||
//sram_hexdump(SRAM_MENU_ADDR, 0x400);
|
||||
while(!cmd) {
|
||||
@ -241,6 +259,11 @@ printf("PCONP=%lx\n", LPC_SC->PCONP);
|
||||
snes_reset(0);
|
||||
break;
|
||||
case SNES_CMD_SETRTC:
|
||||
/* get time from RAM */
|
||||
btime = sram_gettime(SRAM_PARAM_ADDR);
|
||||
/* set RTC */
|
||||
set_bcdtime(btime);
|
||||
set_fpga_time(btime);
|
||||
cmd=0; /* stay in loop */
|
||||
break;
|
||||
default:
|
||||
@ -265,6 +288,11 @@ printf("PCONP=%lx\n", LPC_SC->PCONP);
|
||||
sleep_ms(250);
|
||||
sram_reliable();
|
||||
printf("%s ", get_cic_statename(get_cic_state()));
|
||||
if(reset_changed) {
|
||||
printf("reset\n");
|
||||
reset_changed = 0;
|
||||
fpga_reset_srtc_state();
|
||||
}
|
||||
snes_reset_now=get_snes_reset();
|
||||
if(snes_reset_now) {
|
||||
if(!snes_reset_prev) {
|
||||
|
||||
32
src/memory.c
32
src/memory.c
@ -227,7 +227,7 @@ ticks_total=getticks()-ticksstart;
|
||||
sram_writebyte(0x33, rombase+0xda);
|
||||
sram_writebyte(0x00, rombase+0xd4);
|
||||
sram_writebyte(0xfc, rombase+0xd5);
|
||||
set_fpga_time(0x0020110212180500LL);
|
||||
set_fpga_time(0x0220110301180530LL);
|
||||
}
|
||||
uint32_t rammask;
|
||||
uint32_t rommask;
|
||||
@ -418,3 +418,33 @@ void sram_memset(uint32_t base_addr, uint32_t len, uint8_t val) {
|
||||
FPGA_TX_BYTE(0x00);
|
||||
FPGA_DESELECT();
|
||||
}
|
||||
|
||||
uint64_t sram_gettime(uint32_t base_addr) {
|
||||
set_mcu_addr(base_addr);
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0x88);
|
||||
FPGA_TX_BYTE(0x00);
|
||||
uint8_t data;
|
||||
uint64_t result = 0LL;
|
||||
/* 1st nibble is the century - 10 (binary)
|
||||
4th nibble is the month (binary)
|
||||
all other fields are BCD */
|
||||
for(int i=0; i<12; i++) {
|
||||
data = FPGA_TXRX_BYTE(0x00);
|
||||
data &= 0xf;
|
||||
switch(i) {
|
||||
case 0:
|
||||
result = (result << 4) | ((data / 10) + 1);
|
||||
result = (result << 4) | (data % 10);
|
||||
break;
|
||||
case 3:
|
||||
result = (result << 4) | ((data / 10));
|
||||
result = (result << 4) | (data % 10);
|
||||
break;
|
||||
default:
|
||||
result = (result << 4) | data;
|
||||
}
|
||||
}
|
||||
FPGA_DESELECT();
|
||||
return result & 0x00ffffffffffffffLL;
|
||||
}
|
||||
|
||||
@ -38,6 +38,7 @@
|
||||
#define SRAM_DIR_ADDR (0xE10000L)
|
||||
#define SRAM_CMD_ADDR (0xFF1000L)
|
||||
#define SRAM_PARAM_ADDR (0xFF1004L)
|
||||
#define SRAM_STATUS_ADDR (0xFF1100L)
|
||||
#define SRAM_MENU_SAVE_ADDR (0xFF0000L)
|
||||
#define SRAM_SCRATCHPAD (0xFFFF00L)
|
||||
#define SRAM_DIRID (0xFFFFF0L)
|
||||
@ -61,6 +62,7 @@ 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);
|
||||
void sram_memset(uint32_t base_addr, uint32_t len, uint8_t val);
|
||||
uint64_t sram_gettime(uint32_t base_addr);
|
||||
|
||||
#endif
|
||||
|
||||
69
src/rtc.c
69
src/rtc.c
@ -2,12 +2,22 @@
|
||||
#include <arm/bits.h>
|
||||
#include "config.h"
|
||||
#include "rtc.h"
|
||||
#include "uart.h"
|
||||
#include "timer.h"
|
||||
#include "power.h"
|
||||
|
||||
rtcstate_t rtc_state;
|
||||
|
||||
#define CLKEN 0
|
||||
#define CTCRST 1
|
||||
|
||||
uint8_t rtc_isvalid(void) {
|
||||
if(LPC_RTC->GPREG0 == RTC_MAGIC) {
|
||||
return RTC_OK;
|
||||
}
|
||||
return RTC_INVALID;
|
||||
}
|
||||
|
||||
void rtc_init(void) {
|
||||
if (LPC_RTC->CCR & BV(CLKEN)) {
|
||||
rtc_state = RTC_OK;
|
||||
@ -23,11 +33,25 @@ void read_rtc(struct tm *time) {
|
||||
time->tm_hour = LPC_RTC->HOUR;
|
||||
time->tm_mday = LPC_RTC->DOM;
|
||||
time->tm_mon = LPC_RTC->MONTH;
|
||||
time->tm_year = LPC_RTC->YEAR - 1900;
|
||||
time->tm_year = LPC_RTC->YEAR;
|
||||
time->tm_wday = LPC_RTC->DOW;
|
||||
} while (time->tm_sec != LPC_RTC->SEC);
|
||||
}
|
||||
|
||||
uint8_t calc_weekday(struct tm *time) {
|
||||
int month = time->tm_mon;
|
||||
int year = time->tm_year;
|
||||
int day = time->tm_mday;
|
||||
|
||||
/* Variation of Sillke for the Gregorian calendar.
|
||||
* http://www.mathematik.uni-bielefeld.de/~sillke/ALGORITHMS/calendar/weekday.c */
|
||||
if (month <= 2) {
|
||||
month += 10;
|
||||
year--;
|
||||
} else month -= 2;
|
||||
return (83*month/32 + day + year + year/4 - year/100 + year/400) % 7;
|
||||
}
|
||||
|
||||
void set_rtc(struct tm *time) {
|
||||
LPC_RTC->CCR = BV(CTCRST);
|
||||
LPC_RTC->SEC = time->tm_sec;
|
||||
@ -35,17 +59,21 @@ void set_rtc(struct tm *time) {
|
||||
LPC_RTC->HOUR = time->tm_hour;
|
||||
LPC_RTC->DOM = time->tm_mday;
|
||||
LPC_RTC->MONTH = time->tm_mon;
|
||||
LPC_RTC->YEAR = time->tm_year + 1900;
|
||||
LPC_RTC->DOW = time->tm_wday;
|
||||
LPC_RTC->YEAR = time->tm_year;
|
||||
LPC_RTC->DOW = calc_weekday(time);
|
||||
LPC_RTC->CCR = BV(CLKEN);
|
||||
LPC_RTC->GPREG0 = RTC_MAGIC;
|
||||
}
|
||||
|
||||
void invalidate_rtc() {
|
||||
LPC_RTC->GPREG0 = 0;
|
||||
}
|
||||
|
||||
uint32_t get_fattime(void) {
|
||||
struct tm time;
|
||||
|
||||
read_rtc(&time);
|
||||
return ((uint32_t)time.tm_year-80) << 25 |
|
||||
return ((uint32_t)time.tm_year-1980) << 25 |
|
||||
((uint32_t)time.tm_mon) << 21 |
|
||||
((uint32_t)time.tm_mday) << 16 |
|
||||
((uint32_t)time.tm_hour) << 11 |
|
||||
@ -56,7 +84,7 @@ uint32_t get_fattime(void) {
|
||||
uint64_t get_bcdtime(void) {
|
||||
struct tm time;
|
||||
read_rtc(&time);
|
||||
uint16_t year = time.tm_year + 1900;
|
||||
uint16_t year = time.tm_year;
|
||||
|
||||
return ((uint64_t)(time.tm_wday % 7) << 56)
|
||||
|((uint64_t)((year / 1000) % 10) << 52)
|
||||
@ -74,3 +102,34 @@ uint64_t get_bcdtime(void) {
|
||||
|((time.tm_sec / 10) << 4)
|
||||
|(time.tm_sec % 10);
|
||||
}
|
||||
|
||||
void set_bcdtime(uint64_t btime) {
|
||||
struct tm time;
|
||||
time.tm_sec = (btime & 0xf) + ((btime >> 4) & 0xf) * 10;
|
||||
time.tm_min = ((btime >> 8) & 0xf) + ((btime >> 12) & 0xf) * 10;
|
||||
time.tm_hour = ((btime >> 16) & 0xf) + ((btime >> 20) & 0xf) * 10;
|
||||
time.tm_mday = ((btime >> 24) & 0xf) + ((btime >> 28) & 0xf) * 10;
|
||||
time.tm_mon = ((btime >> 32) & 0xf) + ((btime >> 36) & 0xf) * 10;
|
||||
time.tm_year = ((btime >> 40) & 0xf) + ((btime >> 44) & 0xf) * 10
|
||||
+ ((btime >> 48) & 0xf) * 100 + ((btime >> 52) & 0xf) * 1000;
|
||||
printtime(&time);
|
||||
set_rtc(&time);
|
||||
}
|
||||
|
||||
void printtime(struct tm *time) {
|
||||
printf("%04d-%02d-%02d %02d:%02d:%02d\n", time->tm_year, time->tm_mon,
|
||||
time->tm_mday, time->tm_hour, time->tm_min, time->tm_sec);
|
||||
}
|
||||
|
||||
void testbattery() {
|
||||
printf("%lx\n", LPC_RTC->GPREG0);
|
||||
LPC_RTC->GPREG0 = RTC_MAGIC;
|
||||
printf("%lx\n", LPC_RTC->GPREG0);
|
||||
LPC_RTC->CCR = 0;
|
||||
BITBAND(LPC_SC->PCONP, PCRTC) = 0;
|
||||
delay_ms(20000);
|
||||
BITBAND(LPC_SC->PCONP, PCRTC) = 1;
|
||||
printf("%lx\n", LPC_RTC->GPREG0);
|
||||
delay_ms(20);
|
||||
LPC_RTC->CCR = BV(CLKEN);
|
||||
}
|
||||
|
||||
23
src/rtc.h
23
src/rtc.h
@ -22,9 +22,6 @@
|
||||
|
||||
rtc.h: Definitions for RTC support
|
||||
|
||||
There is no rtc.c, the functions defined here are implemented by a
|
||||
device-specific .c file, e.g. pcf8583.c.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef RTC_H
|
||||
@ -44,22 +41,38 @@ struct tm {
|
||||
uint8_t tm_hour; // 0..23
|
||||
uint8_t tm_mday; // 1..[28..31]
|
||||
uint8_t tm_mon; // 0..11
|
||||
uint8_t tm_year; // since 1900, i.e. 2000 is 100
|
||||
uint16_t tm_year; // since 0 A.D.
|
||||
uint8_t tm_wday; // 0 to 6, sunday is 6
|
||||
// A Unix struct tm has a few more fields we don't need in this application
|
||||
};
|
||||
|
||||
#define RTC_MAGIC (0x43545253L)
|
||||
|
||||
extern rtcstate_t rtc_state;
|
||||
|
||||
void rtc_init(void);
|
||||
|
||||
/* return RTC valid state based on magic token in backup register */
|
||||
uint8_t rtc_isvalid(void);
|
||||
|
||||
/* Return current time in struct tm */
|
||||
void read_rtc(struct tm *time);
|
||||
|
||||
/* Set time from struct tm */
|
||||
/* Set time from struct tm, also sets RTC valid */
|
||||
void set_rtc(struct tm *time);
|
||||
|
||||
/* Set RTC invalid */
|
||||
void invalidate_rtc(void);
|
||||
|
||||
/* get current time in 60-bit BCD format (WYYYYMMDDHHMMSS) (W=DOW) */
|
||||
uint64_t get_bcdtime(void);
|
||||
|
||||
/* set current time from 56-bit BCD format (YYYYMMDDHHMMSS)
|
||||
DOW is calculated */
|
||||
void set_bcdtime(uint64_t btime);
|
||||
|
||||
/* print the time to the console */
|
||||
void printtime(struct tm *time);
|
||||
|
||||
void testbattery(void);
|
||||
#endif
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
#include <stdio.h>
|
||||
#include "config.h"
|
||||
#include "crc.h"
|
||||
#include "crc16.h"
|
||||
#include "diskio.h"
|
||||
#include "spi.h"
|
||||
#include "timer.h"
|
||||
@ -68,12 +69,13 @@
|
||||
#define CARD_SDHC (1<<1)
|
||||
|
||||
/*
|
||||
1 DAT3/SS P0.6
|
||||
2 CMD/DI P0.9
|
||||
5 Clock P0.7
|
||||
7 DAT0/DO P0.8
|
||||
8 DAT1/IRQ P1.14
|
||||
9 DAT2/NC P1.15
|
||||
Rev.A Rev.C
|
||||
1 DAT3/SS P0.6 P2.3
|
||||
2 CMD/DI P0.9 P0.9
|
||||
5 Clock P0.7 P0.7
|
||||
7 DAT0/DO P0.8 P2.0
|
||||
8 DAT1/IRQ P1.14 P2.1
|
||||
9 DAT2/NC P1.15 P2.2
|
||||
*/
|
||||
|
||||
/* SD init procedure
|
||||
@ -197,6 +199,42 @@ static inline void wiggle_fast_pos1(void) {
|
||||
BITBAND(SD_CLKREG->FIOCLR, SD_CLKPIN) = 1;
|
||||
}
|
||||
|
||||
int get_and_check_datacrc(uint8_t *buf) {
|
||||
uint16_t crc0=0, crc1=0, crc2=0, crc3=0;
|
||||
uint16_t sdcrc0=0, sdcrc1=0, sdcrc2=0, sdcrc3=0;
|
||||
uint8_t d0=0, d1=0, d2=0, d3=0;
|
||||
uint8_t datdata;
|
||||
uint16_t datcnt;
|
||||
/* get crcs from card */
|
||||
for (datcnt=0; datcnt < 16; datcnt++) {
|
||||
datdata = SD_DAT;
|
||||
wiggle_fast_neg1();
|
||||
sdcrc0 = ((sdcrc0 << 1) & 0xfffe) | ((datdata >> 3) & 0x0001);
|
||||
sdcrc1 = ((sdcrc1 << 1) & 0xfffe) | ((datdata >> 2) & 0x0001);
|
||||
sdcrc2 = ((sdcrc2 << 1) & 0xfffe) | ((datdata >> 1) & 0x0001);
|
||||
sdcrc3 = ((sdcrc3 << 1) & 0xfffe) | ((datdata >> 0) & 0x0001);
|
||||
}
|
||||
wiggle_fast_neg1();
|
||||
/* calc crcs from data */
|
||||
for (datcnt=0; datcnt < 512; datcnt++) {
|
||||
d0 = ((d0 << 2) & 0xfc) | ((buf[datcnt] >> 6) & 0x02) | ((buf[datcnt] >> 3) & 0x01) ;
|
||||
d1 = ((d1 << 2) & 0xfc) | ((buf[datcnt] >> 5) & 0x02) | ((buf[datcnt] >> 2) & 0x01) ;
|
||||
d2 = ((d2 << 2) & 0xfc) | ((buf[datcnt] >> 4) & 0x02) | ((buf[datcnt] >> 1) & 0x01) ;
|
||||
d3 = ((d3 << 2) & 0xfc) | ((buf[datcnt] >> 3) & 0x02) | ((buf[datcnt] >> 0) & 0x01) ;
|
||||
if((datcnt % 4) == 3) {
|
||||
crc0 = crc_xmodem_update(crc0, d0);
|
||||
crc1 = crc_xmodem_update(crc1, d1);
|
||||
crc2 = crc_xmodem_update(crc2, d2);
|
||||
crc3 = crc_xmodem_update(crc3, d3);
|
||||
}
|
||||
}
|
||||
if((crc0 != sdcrc0) || (crc1 != sdcrc1) || (crc2 != sdcrc2) || (crc3 != sdcrc3)) {
|
||||
printf("CRC mismatch\nSDCRC CRC\n %04x %04x\n %04x %04x\n %04x %04x\n %04x %04x\n", sdcrc0, crc0, sdcrc1, crc1, sdcrc2, crc2, sdcrc3, crc3);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void wait_busy(void) {
|
||||
while(!(BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN))) {
|
||||
wiggle_fast_neg1();
|
||||
@ -459,8 +497,16 @@ int send_command_fast(uint8_t* cmd, uint8_t* rsp, uint8_t* buf){
|
||||
}
|
||||
}
|
||||
}
|
||||
/* just eat the crcs for now */
|
||||
if(dat) wiggle_fast_neg(17);
|
||||
if(dat) {
|
||||
#ifdef CONFIG_SD_DATACRC
|
||||
if(get_and_check_datacrc(buf-512)) {
|
||||
return CRC_ERROR;
|
||||
}
|
||||
#else
|
||||
/* eat the crcs */
|
||||
wiggle_fast_neg(17);
|
||||
#endif
|
||||
}
|
||||
|
||||
if(waitbusy) {
|
||||
DBG_SD printf("waitbusy after send_cmd\n");
|
||||
@ -528,7 +574,7 @@ int acmd_fast(uint8_t cmd, uint32_t param, uint8_t crc, uint8_t* dat, uint8_t* r
|
||||
return cmd_fast(cmd, param, crc, dat, rsp);
|
||||
}
|
||||
|
||||
void stream_datablock(uint8_t *buf) {
|
||||
int stream_datablock(uint8_t *buf) {
|
||||
// uint8_t datshift=8;
|
||||
int j=512;
|
||||
uint8_t datdata=0;
|
||||
@ -559,9 +605,14 @@ void stream_datablock(uint8_t *buf) {
|
||||
j--;
|
||||
if(!j) break;
|
||||
}
|
||||
/* eat the crc for now */
|
||||
wiggle_fast_neg(17);
|
||||
#ifdef CONFIG_SD_DATACRC
|
||||
return get_and_check_datacrc(buf-512);
|
||||
#else
|
||||
/* eat the crcs */
|
||||
wiggle_fast_neg(17);
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void send_datablock(uint8_t *buf) {
|
||||
@ -585,7 +636,7 @@ void send_datablock(uint8_t *buf) {
|
||||
datshift=8;
|
||||
do {
|
||||
datshift-=4;
|
||||
if(((*buf)>>datshift) & 0x8) {
|
||||
/* if(((*buf)>>datshift) & 0x8) {
|
||||
BITBAND(SD_DAT3REG->FIOSET, SD_DAT3PIN) = 1;
|
||||
} else {
|
||||
BITBAND(SD_DAT3REG->FIOCLR, SD_DAT3PIN) = 1;
|
||||
@ -604,7 +655,8 @@ void send_datablock(uint8_t *buf) {
|
||||
BITBAND(SD_DAT0REG->FIOSET, SD_DAT0PIN) = 1;
|
||||
} else {
|
||||
BITBAND(SD_DAT0REG->FIOCLR, SD_DAT0PIN) = 1;
|
||||
}
|
||||
}*/
|
||||
SD_DAT0REG->FIOPIN0 = (*buf) >> datshift;
|
||||
wiggle_fast_pos1();
|
||||
} while (datshift);
|
||||
|
||||
@ -690,7 +742,17 @@ void send_datablock(uint8_t *buf) {
|
||||
void read_block(uint32_t address, uint8_t *buf) {
|
||||
if(during_blocktrans == TRANS_READ && (last_block == address-1)) {
|
||||
//uart_putc('r');
|
||||
#ifdef CONFIG_SD_DATACRC
|
||||
int cmd_res;
|
||||
if((cmd_res = stream_datablock(buf)) == CRC_ERROR) {
|
||||
while(cmd_res == CRC_ERROR) {
|
||||
cmd_fast(STOP_TRANSMISSION, 0, 0x61, NULL, rsp);
|
||||
cmd_res = cmd_fast(READ_MULTIPLE_BLOCK, address, 0, buf, rsp);
|
||||
}
|
||||
}
|
||||
#else
|
||||
stream_datablock(buf);
|
||||
#endif
|
||||
last_block=address;
|
||||
} else {
|
||||
if(during_blocktrans) {
|
||||
@ -703,7 +765,14 @@ void read_block(uint32_t address, uint8_t *buf) {
|
||||
if(!ccs) {
|
||||
address <<= 9;
|
||||
}
|
||||
#ifdef CONFIG_SD_DATACRC
|
||||
while(1) {
|
||||
if(cmd_fast(READ_MULTIPLE_BLOCK, address, 0, buf, rsp) != CRC_ERROR) break;
|
||||
cmd_fast(STOP_TRANSMISSION, 0, 0x61, NULL, rsp);
|
||||
};
|
||||
#else
|
||||
cmd_fast(READ_MULTIPLE_BLOCK, address, 0, buf, rsp);
|
||||
#endif
|
||||
during_blocktrans = TRANS_READ;
|
||||
}
|
||||
}
|
||||
@ -840,6 +909,8 @@ void sdn_init(void) {
|
||||
BITBAND(SD_CLKREG->FIODIR, SD_CLKPIN) = 1;
|
||||
BITBAND(SD_CMDREG->FIODIR, SD_CMDPIN) = 1;
|
||||
BITBAND(SD_CMDREG->FIOPIN, SD_CMDPIN) = 1;
|
||||
LPC_GPIO2->FIOPIN0 = 0x00;
|
||||
LPC_GPIO2->FIOMASK0 = ~0xf;
|
||||
}
|
||||
void disk_init(void) __attribute__ ((weak, alias("sdn_init")));
|
||||
|
||||
|
||||
@ -11,6 +11,8 @@
|
||||
|
||||
#include "diskio.h"
|
||||
|
||||
#define CRC_ERROR (0xf000)
|
||||
|
||||
extern int sd_offload;
|
||||
|
||||
/* These functions are weak-aliased to disk_... */
|
||||
|
||||
@ -43,6 +43,8 @@ uint8_t initloop=1;
|
||||
uint32_t saveram_crc, saveram_crc_old;
|
||||
extern snes_romprops_t romprops;
|
||||
|
||||
volatile int reset_changed;
|
||||
|
||||
void prepare_reset() {
|
||||
set_mcu_ovr(1);
|
||||
snes_reset(1);
|
||||
@ -142,7 +144,7 @@ uint8_t menu_main_loop() {
|
||||
sram_writebyte(0, SRAM_CMD_ADDR);
|
||||
while(!cmd) {
|
||||
if(!get_snes_reset()) {
|
||||
while(!sram_reliable())printf("hurr\n");;
|
||||
while(!sram_reliable())printf("hurr\n");
|
||||
cmd = sram_readbyte(SRAM_CMD_ADDR);
|
||||
}
|
||||
if(get_snes_reset()) {
|
||||
@ -155,7 +157,8 @@ uint8_t menu_main_loop() {
|
||||
}
|
||||
|
||||
void get_selected_name(uint8_t* fn) {
|
||||
uint32_t addr = sram_readlong(SRAM_PARAM_ADDR);
|
||||
uint32_t addr;
|
||||
addr = sram_readlong(SRAM_PARAM_ADDR);
|
||||
printf("fd addr=%lx\n", addr);
|
||||
sram_readblock(fn, addr + 7 + SRAM_MENU_ADDR, 256);
|
||||
}
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
#include "clock.h"
|
||||
#include "uart.h"
|
||||
#include "sdnative.h"
|
||||
#include "snes.h"
|
||||
|
||||
/* bit definitions */
|
||||
#define RITINT 0
|
||||
@ -15,6 +16,7 @@
|
||||
#define PCRIT 16
|
||||
|
||||
extern volatile int sd_changed;
|
||||
extern volatile int reset_changed;
|
||||
volatile tick_t ticks;
|
||||
volatile int wokefromrit;
|
||||
|
||||
@ -26,10 +28,15 @@ void __attribute__((weak,noinline)) SysTick_Hook(void) {
|
||||
void SysTick_Handler(void) {
|
||||
ticks++;
|
||||
static uint16_t sdch_state = 0;
|
||||
static uint16_t reset_state = 0;
|
||||
sdch_state = (sdch_state << 1) | SDCARD_DETECT | 0xe000;
|
||||
if((sdch_state == 0xf000) || (sdch_state == 0xefff)) {
|
||||
sd_changed = 1;
|
||||
}
|
||||
reset_state = (reset_state << 1) | get_snes_reset() | 0xe000;
|
||||
if((reset_state == 0xf000) || (reset_state == 0xefff)) {
|
||||
reset_changed = 1;
|
||||
}
|
||||
sdn_changed();
|
||||
SysTick_Hook();
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user