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.)
|
# 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
|
# 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
|
# cp $(TARGET).bin /mbed/hw_LPC1768.bin
|
||||||
|
|
||||||
|
|
||||||
program: bin
|
program: build
|
||||||
utils/lpcchksum $(TARGET).bin
|
utils/lpcchksum $(TARGET).bin
|
||||||
openocd -f openocd-usb.cfg -f lpc1754.cfg -f flash.cfg
|
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
|
openocd -f openocd-usb.cfg -f lpc1754.cfg
|
||||||
|
|
||||||
reset:
|
reset:
|
||||||
|
|||||||
@ -55,7 +55,7 @@ TARGET = $(OBJDIR)/sd2snes_bootldr
|
|||||||
|
|
||||||
|
|
||||||
# List C source files here. (C dependencies are automatically generated.)
|
# 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
|
# 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,
|
# 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
|
# it will preserve the spelling of the filenames, and gcc itself does
|
||||||
# care about how the name is spelled on its command-line.
|
# 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].
|
# Optimization level, can be [0, 1, 2, 3, s].
|
||||||
|
|||||||
@ -5,17 +5,18 @@
|
|||||||
// #define DEBUG_IRQ
|
// #define DEBUG_IRQ
|
||||||
// #define DEBUG_MSU1
|
// #define DEBUG_MSU1
|
||||||
|
|
||||||
//#define DEBUG_BL
|
#ifdef DEBUG_UART
|
||||||
#ifdef DEBUG_BL
|
#define DBG_UART
|
||||||
#define DBG_BL
|
|
||||||
#else
|
#else
|
||||||
#define DBG_BL while(0)
|
#define DBG_UART while(0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define DBG_BL while(0)
|
||||||
|
|
||||||
#define FW_START (0x00002000L)
|
#define FW_START (0x00002000L)
|
||||||
#define FLASH_SECTORS (17)
|
#define FLASH_SECTORS (17)
|
||||||
|
|
||||||
|
|
||||||
#define VER "0.0.1(NSFW)"
|
#define VER "0.0.1(NSFW)"
|
||||||
#define IN_AHBRAM __attribute__ ((section(".ahbram")))
|
#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_CHANGE_CLR() do {LPC_GPIOINT->IO2IntClr = BV(SD_DT_BIT);} while(0)
|
||||||
|
|
||||||
#define SD_DT_REG LPC_GPIO2
|
#define SD_DT_REG LPC_GPIO0
|
||||||
#define SD_DT_BIT 3
|
#define SD_DT_BIT 8
|
||||||
#define SD_WP_REG LPC_GPIO2
|
#define SD_WP_REG LPC_GPIO0
|
||||||
#define SD_WP_BIT 4
|
#define SD_WP_BIT 6
|
||||||
|
|
||||||
#define SDCARD_DETECT (!(BITBAND(SD_DT_REG->FIOPIN, SD_DT_BIT)))
|
#define SDCARD_DETECT (!(BITBAND(SD_DT_REG->FIOPIN, SD_DT_BIT)))
|
||||||
#define SDCARD_WP (BITBAND(SD_WP_REG->FIOPIN, SD_WP_BIT))
|
#define SDCARD_WP (BITBAND(SD_WP_REG->FIOPIN, SD_WP_BIT))
|
||||||
@ -40,16 +41,16 @@
|
|||||||
#define CONFIG_SD_BLOCKTRANSFER 1
|
#define CONFIG_SD_BLOCKTRANSFER 1
|
||||||
#define CONFIG_SD_AUTO_RETRIES 10
|
#define CONFIG_SD_AUTO_RETRIES 10
|
||||||
// #define SD_CHANGE_VECT
|
// #define SD_CHANGE_VECT
|
||||||
// #define CONFIG_SD_DATACRC 1
|
#define CONFIG_SD_DATACRC 1
|
||||||
|
|
||||||
#define CONFIG_UART_NUM 3
|
#define CONFIG_UART_NUM 3
|
||||||
// #define CONFIG_CPU_FREQUENCY 90315789
|
// #define CONFIG_CPU_FREQUENCY 90315789
|
||||||
#define CONFIG_CPU_FREQUENCY (92000000L)
|
#define CONFIG_CPU_FREQUENCY (92000000L)
|
||||||
//#define CONFIG_CPU_FREQUENCY 46000000
|
//#define CONFIG_CPU_FREQUENCY 46000000
|
||||||
#define CONFIG_UART_PCLKDIV 1
|
#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_BAUDRATE 921600
|
||||||
#define CONFIG_UART_DEADLOCKABLE
|
//#define CONFIG_UART_DEADLOCKABLE
|
||||||
|
|
||||||
#define SSP_CLK_DIVISOR_FAST 2
|
#define SSP_CLK_DIVISOR_FAST 2
|
||||||
#define SSP_CLK_DIVISOR_SLOW 250
|
#define SSP_CLK_DIVISOR_SLOW 250
|
||||||
@ -58,20 +59,19 @@
|
|||||||
#define SSP_CLK_DIVISOR_FPGA_SLOW 20
|
#define SSP_CLK_DIVISOR_FPGA_SLOW 20
|
||||||
|
|
||||||
#define SNES_RESET_REG LPC_GPIO1
|
#define SNES_RESET_REG LPC_GPIO1
|
||||||
#define SNES_RESET_BIT 29
|
#define SNES_RESET_BIT 26
|
||||||
/* XXX Rev.B: 1.26 */
|
|
||||||
#define SNES_CIC_D0_REG LPC_GPIO1
|
#define SNES_CIC_D0_REG LPC_GPIO0
|
||||||
#define SNES_CIC_D0_BIT 26
|
#define SNES_CIC_D0_BIT 1
|
||||||
/* XXX Rev.B: 0.1 */
|
|
||||||
#define SNES_CIC_D1_REG LPC_GPIO1
|
#define SNES_CIC_D1_REG LPC_GPIO0
|
||||||
#define SNES_CIC_D1_BIT 25
|
#define SNES_CIC_D1_BIT 0
|
||||||
/* XXX Rev.B: 0.0 */
|
|
||||||
#define SNES_CIC_STATUS_REG LPC_GPIO0
|
#define SNES_CIC_STATUS_REG LPC_GPIO1
|
||||||
#define SNES_CIC_STATUS_BIT 1
|
#define SNES_CIC_STATUS_BIT 29
|
||||||
/* XXX Rev.B: 1.29 */
|
|
||||||
#define SNES_CIC_PAIR_REG LPC_GPIO0
|
#define SNES_CIC_PAIR_REG LPC_GPIO1
|
||||||
#define SNES_CIC_PAIR_BIT 0
|
#define SNES_CIC_PAIR_BIT 25
|
||||||
/* XXX Rev.B: 1.25 */
|
|
||||||
|
|
||||||
#define QSORT_MAXELEM 1024
|
#define QSORT_MAXELEM 1024
|
||||||
|
|
||||||
@ -88,20 +88,18 @@
|
|||||||
|
|
||||||
#define SD_CLKREG LPC_GPIO0
|
#define SD_CLKREG LPC_GPIO0
|
||||||
#define SD_CMDREG LPC_GPIO0
|
#define SD_CMDREG LPC_GPIO0
|
||||||
#define SD_DAT0REG LPC_GPIO0
|
#define SD_DAT0REG LPC_GPIO2
|
||||||
#define SD_DAT1REG LPC_GPIO1
|
#define SD_DAT1REG LPC_GPIO2
|
||||||
#define SD_DAT2REG LPC_GPIO1
|
#define SD_DAT2REG LPC_GPIO2
|
||||||
#define SD_DAT3REG LPC_GPIO0
|
#define SD_DAT3REG LPC_GPIO2
|
||||||
|
|
||||||
#define SD_CLKPIN (7)
|
#define SD_CLKPIN (7)
|
||||||
#define SD_CMDPIN (9)
|
#define SD_CMDPIN (9)
|
||||||
#define SD_DAT0PIN (8)
|
#define SD_DAT0PIN (0)
|
||||||
#define SD_DAT1PIN (14)
|
#define SD_DAT1PIN (1)
|
||||||
#define SD_DAT2PIN (15)
|
#define SD_DAT2PIN (2)
|
||||||
#define SD_DAT3PIN (6)
|
#define SD_DAT3PIN (3)
|
||||||
|
|
||||||
#define SD_DAT ((BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN))\
|
#define SD_DAT (LPC_GPIO2->FIOPIN & 0xf)
|
||||||
|((SD_DAT1REG->FIOPIN1 >> 5) & 0x6)\
|
|
||||||
|((BITBAND(SD_DAT3REG->FIOPIN, SD_DAT3PIN)) << 3))
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -26,22 +26,6 @@ loop:
|
|||||||
uxtb r0, r0 // clear top bits of result
|
uxtb r0, r0 // clear top bits of result
|
||||||
bx lr // return
|
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) */
|
/* uint16_t crc_xmodem_block(uint16_t crc, uint8_t *data, uint32_t len) */
|
||||||
.global crc_xmodem_update
|
.global crc_xmodem_update
|
||||||
.thumb_func
|
.thumb_func
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
void HardFault_Handler(void) {
|
void HardFault_Handler(void) {
|
||||||
DBG_BL printf("HFSR: %lx\n", SCB->HFSR);
|
DBG_BL printf("HFSR: %lx\n", SCB->HFSR);
|
||||||
uart_putc('H');
|
DBG_UART uart_putc('H');
|
||||||
while (1) ;
|
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));
|
mem_cpy(rbuff + ((fp->fs->winsect - sect) * SS(fp->fs)), fp->fs->win, SS(fp->fs));
|
||||||
#else
|
#else
|
||||||
if ((fp->flag & FA__DIRTY) && fp->dsect - sect < cc){
|
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
|
||||||
#endif
|
#endif
|
||||||
rcnt = SS(fp->fs) * cc; /* Number of bytes transferred */
|
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("firmware image found. file size: %ld\n", file_handle.fsize);
|
||||||
DBG_BL printf("reading header...\n");
|
DBG_BL printf("reading header...\n");
|
||||||
f_read(&file_handle, &file_header, 32, &bytes_read);
|
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) {
|
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);
|
f_read(&file_handle, file_buf, 0xe0, &bytes_read);
|
||||||
for(;;) {
|
for(;;) {
|
||||||
bytes_read = file_read();
|
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))
|
current_sec = flash_addr & 0x10000 ? (16 + ((flash_addr >> 15) & 1))
|
||||||
: (flash_addr >> 12);
|
: (flash_addr >> 12);
|
||||||
DBG_BL printf("current_sec=%d flash_addr=%08lx\n", current_sec, flash_addr);
|
DBG_BL printf("current_sec=%d flash_addr=%08lx\n", current_sec, flash_addr);
|
||||||
uart_putc('.');
|
DBG_UART uart_putc('.');
|
||||||
toggle_rdy_led();
|
toggle_rdy_led();
|
||||||
if(current_sec < (FW_START / 0x1000)) return ERR_FLASH;
|
if(current_sec < (FW_START / 0x1000)) return ERR_FLASH;
|
||||||
if((res = iap_prepare_for_write(current_sec, current_sec)) != CMD_SUCCESS) {
|
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) {
|
if(total_read != file_header.size) {
|
||||||
DBG_BL printf("wrote less data than expected! (%08lx vs. %08lx)\n", 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;
|
return ERR_FILECHK;
|
||||||
}
|
}
|
||||||
} else {
|
} 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");
|
DBG_BL printf("flash content is ok, no version mismatch, no forced upgrade. No need to flash\n");
|
||||||
}
|
}
|
||||||
return ERR_OK;
|
return ERR_OK;
|
||||||
|
|||||||
@ -9,18 +9,27 @@ int led_rdyledstate = 0;
|
|||||||
int led_readledstate = 0;
|
int led_readledstate = 0;
|
||||||
int led_writeledstate = 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) {
|
void rdyled(unsigned int state) {
|
||||||
BITBAND(LPC_GPIO2->FIODIR, 0) = state;
|
BITBAND(LPC_GPIO2->FIODIR, 4) = state;
|
||||||
led_rdyledstate = state;
|
led_rdyledstate = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
void readled(unsigned int state) {
|
void readled(unsigned int state) {
|
||||||
BITBAND(LPC_GPIO2->FIODIR, 1) = state;
|
BITBAND(LPC_GPIO2->FIODIR, 5) = state;
|
||||||
led_readledstate = state;
|
led_readledstate = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeled(unsigned int state) {
|
void writeled(unsigned int state) {
|
||||||
BITBAND(LPC_GPIO2->FIODIR, 2) = state;
|
BITBAND(LPC_GPIO1->FIODIR, 23) = state;
|
||||||
led_writeledstate = state;
|
led_writeledstate = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,7 +45,7 @@ void led_clkout32(uint32_t val) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void toggle_rdy_led() {
|
void toggle_rdy_led() {
|
||||||
rdyled(!led_rdyledstate);
|
rdyled(~led_rdyledstate);
|
||||||
}
|
}
|
||||||
|
|
||||||
void toggle_read_led() {
|
void toggle_read_led() {
|
||||||
@ -49,21 +58,28 @@ void toggle_write_led() {
|
|||||||
|
|
||||||
void led_panic() {
|
void led_panic() {
|
||||||
while(1) {
|
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);
|
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);
|
delay_ms(350);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void led_std() {
|
void led_std() {
|
||||||
BITBAND(LPC_PINCON->PINSEL4, 1) = 0;
|
BITBAND(LPC_PINCON->PINSEL4, 9) = 0;
|
||||||
BITBAND(LPC_PINCON->PINSEL4, 3) = 0;
|
BITBAND(LPC_PINCON->PINSEL4, 8) = 0;
|
||||||
BITBAND(LPC_PINCON->PINSEL4, 5) = 0;
|
|
||||||
|
|
||||||
BITBAND(LPC_PINCON->PINSEL4, 0) = 0;
|
BITBAND(LPC_PINCON->PINSEL4, 11) = 0;
|
||||||
BITBAND(LPC_PINCON->PINSEL4, 2) = 0;
|
BITBAND(LPC_PINCON->PINSEL4, 10) = 0;
|
||||||
BITBAND(LPC_PINCON->PINSEL4, 4) = 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() {
|
void led_init() {
|
||||||
|
|||||||
@ -10,7 +10,7 @@ ENTRY(_start)
|
|||||||
|
|
||||||
MEMORY
|
MEMORY
|
||||||
{
|
{
|
||||||
flash (rx) : ORIGIN = 0x00000000, LENGTH = 0x03000
|
flash (rx) : ORIGIN = 0x00000000, LENGTH = 0x02000
|
||||||
ram (rwx) : ORIGIN = 0x10000000, LENGTH = 0x03fe0 /* leave room for IAP */
|
ram (rwx) : ORIGIN = 0x10000000, LENGTH = 0x03fe0 /* leave room for IAP */
|
||||||
ahbram (rwx) : ORIGIN = 0x2007C000, LENGTH = 0x04000
|
ahbram (rwx) : ORIGIN = 0x2007C000, LENGTH = 0x04000
|
||||||
}
|
}
|
||||||
|
|||||||
@ -42,7 +42,7 @@ int main(void) {
|
|||||||
clock_disconnect();
|
clock_disconnect();
|
||||||
power_init();
|
power_init();
|
||||||
timer_init();
|
timer_init();
|
||||||
uart_init();
|
DBG_UART uart_init();
|
||||||
led_init();
|
led_init();
|
||||||
readled(0);
|
readled(0);
|
||||||
rdyled(0);
|
rdyled(0);
|
||||||
|
|||||||
@ -66,12 +66,13 @@
|
|||||||
#define CARD_SDHC (1<<1)
|
#define CARD_SDHC (1<<1)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
1 DAT3/SS P0.6
|
Rev.A Rev.C
|
||||||
2 CMD/DI P0.9
|
1 DAT3/SS P0.6 P2.3
|
||||||
5 Clock P0.7
|
2 CMD/DI P0.9 P0.9
|
||||||
7 DAT0/DO P0.8
|
5 Clock P0.7 P0.7
|
||||||
8 DAT1/IRQ P1.14
|
7 DAT0/DO P0.8 P2.0
|
||||||
9 DAT2/NC P1.15
|
8 DAT1/IRQ P1.14 P2.1
|
||||||
|
9 DAT2/NC P1.15 P2.2
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* SD init procedure
|
/* SD init procedure
|
||||||
@ -195,6 +196,42 @@ static inline void wiggle_fast_pos1(void) {
|
|||||||
BITBAND(SD_CLKREG->FIOCLR, SD_CLKPIN) = 1;
|
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) {
|
static inline void wait_busy(void) {
|
||||||
while(!(BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN))) {
|
while(!(BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN))) {
|
||||||
wiggle_fast_neg1();
|
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) {
|
||||||
if(dat) wiggle_fast_neg(17);
|
#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) {
|
if(waitbusy) {
|
||||||
DBG_SD printf("waitbusy after send_cmd\n");
|
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);
|
return cmd_fast(cmd, param, crc, dat, rsp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void stream_datablock(uint8_t *buf) {
|
int stream_datablock(uint8_t *buf) {
|
||||||
// uint8_t datshift=8;
|
// uint8_t datshift=8;
|
||||||
int j=512;
|
int j=512;
|
||||||
uint8_t datdata=0;
|
uint8_t datdata=0;
|
||||||
@ -537,8 +582,13 @@ void stream_datablock(uint8_t *buf) {
|
|||||||
j--;
|
j--;
|
||||||
if(!j) break;
|
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);
|
wiggle_fast_neg(17);
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void send_datablock(uint8_t *buf) {
|
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) {
|
void read_block(uint32_t address, uint8_t *buf) {
|
||||||
if(during_blocktrans == TRANS_READ && (last_block == address-1)) {
|
if(during_blocktrans == TRANS_READ && (last_block == address-1)) {
|
||||||
//uart_putc('r');
|
//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);
|
stream_datablock(buf);
|
||||||
|
#endif
|
||||||
last_block=address;
|
last_block=address;
|
||||||
} else {
|
} else {
|
||||||
if(during_blocktrans) {
|
if(during_blocktrans) {
|
||||||
@ -680,7 +740,14 @@ void read_block(uint32_t address, uint8_t *buf) {
|
|||||||
if(!ccs) {
|
if(!ccs) {
|
||||||
address <<= 9;
|
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);
|
cmd_fast(READ_MULTIPLE_BLOCK, address, 0, buf, rsp);
|
||||||
|
#endif
|
||||||
during_blocktrans = TRANS_READ;
|
during_blocktrans = TRANS_READ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
#include "diskio.h"
|
#include "diskio.h"
|
||||||
|
|
||||||
|
#define CRC_ERROR (0xf000)
|
||||||
|
|
||||||
/* These functions are weak-aliased to disk_... */
|
/* These functions are weak-aliased to disk_... */
|
||||||
void sdn_init(void);
|
void sdn_init(void);
|
||||||
DSTATUS sdn_status(BYTE drv);
|
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;
|
curchar[4+2] = 0;
|
||||||
time.tm_mon = atoi(curchar+4);
|
time.tm_mon = atoi(curchar+4);
|
||||||
curchar[4] = 0;
|
curchar[4] = 0;
|
||||||
time.tm_year = atoi(curchar) - 1900;
|
time.tm_year = atoi(curchar);
|
||||||
set_rtc(&time);
|
set_rtc(&time);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -396,7 +396,7 @@ void cmd_settime(void) {
|
|||||||
void cmd_time(void) {
|
void cmd_time(void) {
|
||||||
struct tm time;
|
struct tm time;
|
||||||
read_rtc(&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);
|
time.tm_mday, time.tm_hour, time.tm_min, time.tm_sec);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -513,6 +513,11 @@ void cli_loop(void) {
|
|||||||
case CMD_TIME:
|
case CMD_TIME:
|
||||||
cmd_time();
|
cmd_time();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CMD_TEST:
|
||||||
|
testbattery();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -49,7 +49,8 @@ void clock_init() {
|
|||||||
enableMainOsc();
|
enableMainOsc();
|
||||||
setClkSrc(CLKSRC_MAINOSC);
|
setClkSrc(CLKSRC_MAINOSC);
|
||||||
// XXX setPLL0MultPrediv(429, 19);
|
// XXX setPLL0MultPrediv(429, 19);
|
||||||
setPLL0MultPrediv(23, 2);
|
// XXX setPLL0MultPrediv(23, 2);
|
||||||
|
setPLL0MultPrediv(12, 1);
|
||||||
enablePLL0();
|
enablePLL0();
|
||||||
setCCLKDiv(3);
|
setCCLKDiv(3);
|
||||||
connectPLL0();
|
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_CHANGE_CLR() do {LPC_GPIOINT->IO2IntClr = BV(SD_DT_BIT);} while(0)
|
||||||
|
|
||||||
#define SD_DT_REG LPC_GPIO2
|
#define SD_DT_REG LPC_GPIO0
|
||||||
#define SD_DT_BIT 3
|
#define SD_DT_BIT 8
|
||||||
#define SD_WP_REG LPC_GPIO2
|
#define SD_WP_REG LPC_GPIO0
|
||||||
#define SD_WP_BIT 4
|
#define SD_WP_BIT 6
|
||||||
|
|
||||||
#define SDCARD_DETECT (!(BITBAND(SD_DT_REG->FIOPIN, SD_DT_BIT)))
|
#define SDCARD_DETECT (!(BITBAND(SD_DT_REG->FIOPIN, SD_DT_BIT)))
|
||||||
#define SDCARD_WP (BITBAND(SD_WP_REG->FIOPIN, SD_WP_BIT))
|
#define SDCARD_WP (BITBAND(SD_WP_REG->FIOPIN, SD_WP_BIT))
|
||||||
@ -33,12 +33,12 @@
|
|||||||
|
|
||||||
#define CONFIG_UART_NUM 3
|
#define CONFIG_UART_NUM 3
|
||||||
// #define CONFIG_CPU_FREQUENCY 90315789
|
// #define CONFIG_CPU_FREQUENCY 90315789
|
||||||
#define CONFIG_CPU_FREQUENCY 92000000
|
#define CONFIG_CPU_FREQUENCY 96000000
|
||||||
//#define CONFIG_CPU_FREQUENCY 46000000
|
//#define CONFIG_CPU_FREQUENCY 46000000
|
||||||
#define CONFIG_UART_PCLKDIV 1
|
#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_BAUDRATE 921600
|
||||||
//#define CONFIG_UART_DEADLOCKABLE
|
#define CONFIG_UART_DEADLOCKABLE
|
||||||
|
|
||||||
#define SSP_CLK_DIVISOR_FAST 2
|
#define SSP_CLK_DIVISOR_FAST 2
|
||||||
#define SSP_CLK_DIVISOR_SLOW 250
|
#define SSP_CLK_DIVISOR_SLOW 250
|
||||||
@ -47,20 +47,19 @@
|
|||||||
#define SSP_CLK_DIVISOR_FPGA_SLOW 20
|
#define SSP_CLK_DIVISOR_FPGA_SLOW 20
|
||||||
|
|
||||||
#define SNES_RESET_REG LPC_GPIO1
|
#define SNES_RESET_REG LPC_GPIO1
|
||||||
#define SNES_RESET_BIT 29
|
#define SNES_RESET_BIT 26
|
||||||
/* XXX Rev.B: 1.26 */
|
|
||||||
#define SNES_CIC_D0_REG LPC_GPIO1
|
#define SNES_CIC_D0_REG LPC_GPIO0
|
||||||
#define SNES_CIC_D0_BIT 26
|
#define SNES_CIC_D0_BIT 1
|
||||||
/* XXX Rev.B: 0.1 */
|
|
||||||
#define SNES_CIC_D1_REG LPC_GPIO1
|
#define SNES_CIC_D1_REG LPC_GPIO0
|
||||||
#define SNES_CIC_D1_BIT 25
|
#define SNES_CIC_D1_BIT 0
|
||||||
/* XXX Rev.B: 0.0 */
|
|
||||||
#define SNES_CIC_STATUS_REG LPC_GPIO0
|
#define SNES_CIC_STATUS_REG LPC_GPIO1
|
||||||
#define SNES_CIC_STATUS_BIT 1
|
#define SNES_CIC_STATUS_BIT 29
|
||||||
/* XXX Rev.B: 1.29 */
|
|
||||||
#define SNES_CIC_PAIR_REG LPC_GPIO0
|
#define SNES_CIC_PAIR_REG LPC_GPIO1
|
||||||
#define SNES_CIC_PAIR_BIT 0
|
#define SNES_CIC_PAIR_BIT 25
|
||||||
/* XXX Rev.B: 1.25 */
|
|
||||||
|
|
||||||
#define QSORT_MAXELEM 1024
|
#define QSORT_MAXELEM 1024
|
||||||
|
|
||||||
@ -77,20 +76,18 @@
|
|||||||
|
|
||||||
#define SD_CLKREG LPC_GPIO0
|
#define SD_CLKREG LPC_GPIO0
|
||||||
#define SD_CMDREG LPC_GPIO0
|
#define SD_CMDREG LPC_GPIO0
|
||||||
#define SD_DAT0REG LPC_GPIO0
|
#define SD_DAT0REG LPC_GPIO2
|
||||||
#define SD_DAT1REG LPC_GPIO1
|
#define SD_DAT1REG LPC_GPIO2
|
||||||
#define SD_DAT2REG LPC_GPIO1
|
#define SD_DAT2REG LPC_GPIO2
|
||||||
#define SD_DAT3REG LPC_GPIO0
|
#define SD_DAT3REG LPC_GPIO2
|
||||||
|
|
||||||
#define SD_CLKPIN (7)
|
#define SD_CLKPIN (7)
|
||||||
#define SD_CMDPIN (9)
|
#define SD_CMDPIN (9)
|
||||||
#define SD_DAT0PIN (8)
|
#define SD_DAT0PIN (0)
|
||||||
#define SD_DAT1PIN (14)
|
#define SD_DAT1PIN (1)
|
||||||
#define SD_DAT2PIN (15)
|
#define SD_DAT2PIN (2)
|
||||||
#define SD_DAT3PIN (6)
|
#define SD_DAT3PIN (3)
|
||||||
|
|
||||||
#define SD_DAT ((BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN))\
|
#define SD_DAT (LPC_GPIO2->FIOPIN0)
|
||||||
|((SD_DAT1REG->FIOPIN1 >> 5) & 0x6)\
|
|
||||||
|((BITBAND(SD_DAT3REG->FIOPIN, SD_DAT3PIN)) << 3))
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
11
src/crc16.c
11
src/crc16.c
@ -20,7 +20,7 @@
|
|||||||
/**
|
/**
|
||||||
* Static table used for the table_driven implementation.
|
* 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,
|
0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241,
|
||||||
0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440,
|
0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440,
|
||||||
0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40,
|
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.
|
* \param data_len Number of bytes in the \a data buffer.
|
||||||
* \return The updated crc value.
|
* \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;
|
unsigned int tbl_idx;
|
||||||
while (data_len--) {
|
tbl_idx = (crc ^ data) & 0xff;
|
||||||
tbl_idx = (crc ^ *data) & 0xff;
|
crc = (crc_table[tbl_idx] ^ (crc >> 8)) & 0xffff;
|
||||||
crc = (crc_table[tbl_idx] ^ (crc >> 8)) & 0xffff;
|
|
||||||
data++;
|
|
||||||
}
|
|
||||||
return crc & 0xffff;
|
return crc & 0xffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -29,13 +29,6 @@ extern "C" {
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
#define CRC_ALGO_BIT_BY_BIT_FAST 1
|
#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.
|
* 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.
|
* \param data_len Number of bytes in the \a data buffer.
|
||||||
* \return The updated crc value.
|
* \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
|
#ifdef __cplusplus
|
||||||
} /* closing brace for extern "C" */
|
} /* 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;
|
this_dir_tgt = SRAM_DIR_ADDR;
|
||||||
parent_tgt = 0;
|
parent_tgt = 0;
|
||||||
printf("root dir @%lx\n", dir_tgt);
|
printf("root dir @%lx\n", dir_tgt);
|
||||||
}
|
}
|
||||||
|
|
||||||
fno.lfsize = 255;
|
fno.lfsize = 255;
|
||||||
fno.lfname = (TCHAR*)file_lfn;
|
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);
|
strncpy(path+len+1, (char*)fn, sizeof(fs_path)-len);
|
||||||
uint16_t pathlen = strlen(path);
|
uint16_t pathlen = strlen(path);
|
||||||
switch(type) {
|
switch(type) {
|
||||||
|
case TYPE_IPS:
|
||||||
case TYPE_SMC:
|
case TYPE_SMC:
|
||||||
/* file_open_by_filinfo(&fno);
|
/* file_open_by_filinfo(&fno);
|
||||||
if(file_res){
|
if(file_res){
|
||||||
@ -194,7 +195,7 @@ uint32_t scan_dir(char* path, char mkdb, uint32_t this_dir_tgt) {
|
|||||||
db_tgt += 0x00010000;
|
db_tgt += 0x00010000;
|
||||||
printf("new=%lx\n", db_tgt);
|
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;
|
dir_tgt += 4;
|
||||||
/* save element:
|
/* save element:
|
||||||
- index of last slash character
|
- index of last slash character
|
||||||
@ -252,7 +253,13 @@ SNES_FTYPE determine_filetype(char* filename) {
|
|||||||
||(!strcasecmp(ext+1, "FIG"))
|
||(!strcasecmp(ext+1, "FIG"))
|
||||||
) {
|
) {
|
||||||
return TYPE_SMC;
|
return TYPE_SMC;
|
||||||
}/* later
|
}
|
||||||
|
if( (!strcasecmp(ext+1, "IPS"))
|
||||||
|
||(!strcasecmp(ext+1, "UPS"))
|
||||||
|
) {
|
||||||
|
return TYPE_IPS;
|
||||||
|
}
|
||||||
|
/* later
|
||||||
if(!strcasecmp_P(ext+1, PSTR("SRM"))) {
|
if(!strcasecmp_P(ext+1, PSTR("SRM"))) {
|
||||||
return TYPE_SRM;
|
return TYPE_SRM;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,10 +29,11 @@
|
|||||||
|
|
||||||
#include "ff.h"
|
#include "ff.h"
|
||||||
typedef enum {
|
typedef enum {
|
||||||
TYPE_UNKNOWN = 0, /* 0 */
|
TYPE_UNKNOWN = 0, /* 0 */
|
||||||
TYPE_SMC, /* 1 */
|
TYPE_SMC, /* 1 */
|
||||||
TYPE_SRM, /* 2 */
|
TYPE_SRM, /* 2 */
|
||||||
TYPE_SPC /* 3 */
|
TYPE_SPC, /* 3 */
|
||||||
|
TYPE_IPS /* 4 */
|
||||||
} SNES_FTYPE;
|
} SNES_FTYPE;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
#flash info 0
|
#flash info 0
|
||||||
|
|
||||||
reset init
|
reset init
|
||||||
flash write_image erase unlock obj/sd2snes.elf
|
flash write_image erase unlock obj/firmware.img 8192
|
||||||
reset run
|
reset run
|
||||||
shutdown
|
shutdown
|
||||||
|
|
||||||
|
|||||||
@ -53,10 +53,10 @@
|
|||||||
|
|
||||||
8p - read (RAM only)
|
8p - read (RAM only)
|
||||||
p: 0 = no increment after read
|
p: 0 = no increment after read
|
||||||
1 = increment after read
|
8 = increment after read
|
||||||
|
|
||||||
9p {xx}* write xx
|
9p {xx}* write xx
|
||||||
p: tt-i
|
p: i-tt
|
||||||
tt = target (see above)
|
tt = target (see above)
|
||||||
i = increment (see above)
|
i = increment (see above)
|
||||||
|
|
||||||
@ -73,6 +73,7 @@
|
|||||||
nibbles packed)
|
nibbles packed)
|
||||||
eg 0x20111210094816 is 2011-12-10, 9:48:16
|
eg 0x20111210094816 is 2011-12-10, 9:48:16
|
||||||
E6 ssrr set/reset BS-X status register [7:0]
|
E6 ssrr set/reset BS-X status register [7:0]
|
||||||
|
E7 - reset SRTC state
|
||||||
F0 - receive test token (to see if FPGA is alive)
|
F0 - receive test token (to see if FPGA is alive)
|
||||||
F1 - receive status (16bit, MSB first), see below
|
F1 - receive status (16bit, MSB first), see below
|
||||||
|
|
||||||
@ -336,3 +337,11 @@ void set_fpga_time(uint64_t time) {
|
|||||||
FPGA_TX_BYTE(0x00);
|
FPGA_TX_BYTE(0x00);
|
||||||
FPGA_DESELECT();
|
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);
|
uint32_t get_snes_sysclk(void);
|
||||||
void set_bsx_regs(uint8_t set, uint8_t reset);
|
void set_bsx_regs(uint8_t set, uint8_t reset);
|
||||||
void set_fpga_time(uint64_t time);
|
void set_fpga_time(uint64_t time);
|
||||||
|
void fpga_reset_srtc_state(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
74
src/led.c
74
src/led.c
@ -12,11 +12,20 @@ int led_readledstate = 0;
|
|||||||
int led_writeledstate = 0;
|
int led_writeledstate = 0;
|
||||||
int led_pwmstate = 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) {
|
void rdyled(unsigned int state) {
|
||||||
if(led_pwmstate) {
|
if(led_pwmstate) {
|
||||||
rdybright(state?15:0);
|
rdybright(state?15:0);
|
||||||
} else {
|
} else {
|
||||||
BITBAND(LPC_GPIO2->FIODIR, 0) = state;
|
BITBAND(LPC_GPIO2->FIODIR, 4) = state;
|
||||||
}
|
}
|
||||||
led_rdyledstate = state;
|
led_rdyledstate = state;
|
||||||
}
|
}
|
||||||
@ -25,7 +34,7 @@ void readled(unsigned int state) {
|
|||||||
if(led_pwmstate) {
|
if(led_pwmstate) {
|
||||||
readbright(state?15:0);
|
readbright(state?15:0);
|
||||||
} else {
|
} else {
|
||||||
BITBAND(LPC_GPIO2->FIODIR, 1) = state;
|
BITBAND(LPC_GPIO2->FIODIR, 5) = state;
|
||||||
}
|
}
|
||||||
led_readledstate = state;
|
led_readledstate = state;
|
||||||
}
|
}
|
||||||
@ -34,22 +43,22 @@ void writeled(unsigned int state) {
|
|||||||
if(led_pwmstate) {
|
if(led_pwmstate) {
|
||||||
writebright(state?15:0);
|
writebright(state?15:0);
|
||||||
} else {
|
} else {
|
||||||
BITBAND(LPC_GPIO2->FIODIR, 2) = state;
|
BITBAND(LPC_GPIO1->FIODIR, 23) = state;
|
||||||
}
|
}
|
||||||
led_writeledstate = state;
|
led_writeledstate = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rdybright(uint8_t bright) {
|
void rdybright(uint8_t bright) {
|
||||||
LPC_PWM1->MR1 = led_bright[(bright & 15)];
|
LPC_PWM1->MR5 = led_bright[(bright & 15)];
|
||||||
BITBAND(LPC_PWM1->LER, 1) = 1;
|
BITBAND(LPC_PWM1->LER, 5) = 1;
|
||||||
}
|
}
|
||||||
void readbright(uint8_t bright) {
|
void readbright(uint8_t bright) {
|
||||||
LPC_PWM1->MR2 = led_bright[(bright & 15)];
|
LPC_PWM1->MR6 = led_bright[(bright & 15)];
|
||||||
BITBAND(LPC_PWM1->LER, 2) = 1;
|
BITBAND(LPC_PWM1->LER, 6) = 1;
|
||||||
}
|
}
|
||||||
void writebright(uint8_t bright) {
|
void writebright(uint8_t bright) {
|
||||||
LPC_PWM1->MR3 = led_bright[(bright & 15)];
|
LPC_PWM1->MR4 = led_bright[(bright & 15)];
|
||||||
BITBAND(LPC_PWM1->LER, 3) = 1;
|
BITBAND(LPC_PWM1->LER, 4) = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void led_clkout32(uint32_t val) {
|
void led_clkout32(uint32_t val) {
|
||||||
@ -77,43 +86,46 @@ void toggle_write_led() {
|
|||||||
|
|
||||||
void led_panic() {
|
void led_panic() {
|
||||||
while(1) {
|
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);
|
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);
|
delay_ms(350);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void led_pwm() {
|
void led_pwm() {
|
||||||
/* connect PWM to P2.0 - P2.2 */
|
/* Rev.C P2.4, P2.5, P1.23 */
|
||||||
/* XXX Rev.B P2.???? */
|
BITBAND(LPC_PINCON->PINSEL4, 9) = 0;
|
||||||
BITBAND(LPC_PINCON->PINSEL4, 1) = 0;
|
BITBAND(LPC_PINCON->PINSEL4, 8) = 1;
|
||||||
BITBAND(LPC_PINCON->PINSEL4, 3) = 0;
|
|
||||||
BITBAND(LPC_PINCON->PINSEL4, 5) = 0;
|
|
||||||
|
|
||||||
BITBAND(LPC_PINCON->PINSEL4, 0) = 1;
|
BITBAND(LPC_PINCON->PINSEL4, 11) = 0;
|
||||||
BITBAND(LPC_PINCON->PINSEL4, 2) = 1;
|
BITBAND(LPC_PINCON->PINSEL4, 10) = 1;
|
||||||
BITBAND(LPC_PINCON->PINSEL4, 4) = 1;
|
|
||||||
|
|
||||||
BITBAND(LPC_PWM1->PCR, 9) = 1;
|
BITBAND(LPC_PINCON->PINSEL3, 15) = 1;
|
||||||
BITBAND(LPC_PWM1->PCR, 10) = 1;
|
BITBAND(LPC_PINCON->PINSEL3, 14) = 0;
|
||||||
BITBAND(LPC_PWM1->PCR, 11) = 1;
|
|
||||||
|
BITBAND(LPC_PWM1->PCR, 12) = 1;
|
||||||
|
BITBAND(LPC_PWM1->PCR, 13) = 1;
|
||||||
|
BITBAND(LPC_PWM1->PCR, 14) = 1;
|
||||||
|
|
||||||
led_pwmstate = 1;
|
led_pwmstate = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void led_std() {
|
void led_std() {
|
||||||
BITBAND(LPC_PINCON->PINSEL4, 1) = 0;
|
BITBAND(LPC_PINCON->PINSEL4, 9) = 0;
|
||||||
BITBAND(LPC_PINCON->PINSEL4, 3) = 0;
|
BITBAND(LPC_PINCON->PINSEL4, 8) = 0;
|
||||||
BITBAND(LPC_PINCON->PINSEL4, 5) = 0;
|
|
||||||
|
|
||||||
BITBAND(LPC_PINCON->PINSEL4, 0) = 0;
|
BITBAND(LPC_PINCON->PINSEL4, 11) = 0;
|
||||||
BITBAND(LPC_PINCON->PINSEL4, 2) = 0;
|
BITBAND(LPC_PINCON->PINSEL4, 10) = 0;
|
||||||
BITBAND(LPC_PINCON->PINSEL4, 4) = 0;
|
|
||||||
|
|
||||||
BITBAND(LPC_PWM1->PCR, 9) = 0;
|
BITBAND(LPC_PINCON->PINSEL3, 15) = 0;
|
||||||
BITBAND(LPC_PWM1->PCR, 10) = 0;
|
BITBAND(LPC_PINCON->PINSEL3, 14) = 0;
|
||||||
BITBAND(LPC_PWM1->PCR, 11) = 0;
|
|
||||||
|
BITBAND(LPC_PWM1->PCR, 12) = 0;
|
||||||
|
BITBAND(LPC_PWM1->PCR, 13) = 0;
|
||||||
|
BITBAND(LPC_PWM1->PCR, 14) = 0;
|
||||||
|
|
||||||
led_pwmstate = 0;
|
led_pwmstate = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,7 +10,7 @@ ENTRY(_start)
|
|||||||
|
|
||||||
MEMORY
|
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
|
ram (rwx) : ORIGIN = 0x10000000, LENGTH = 0x04000
|
||||||
ahbram (rwx) : ORIGIN = 0x2007C000, LENGTH = 0x04000
|
ahbram (rwx) : ORIGIN = 0x2007C000, LENGTH = 0x04000
|
||||||
}
|
}
|
||||||
|
|||||||
48
src/main.c
48
src/main.c
@ -25,8 +25,8 @@
|
|||||||
#include "crc.h"
|
#include "crc.h"
|
||||||
#include "smc.h"
|
#include "smc.h"
|
||||||
#include "msu1.h"
|
#include "msu1.h"
|
||||||
|
#include "rtc.h"
|
||||||
|
|
||||||
#include "usb_hid.h"
|
|
||||||
#define EMC0TOGGLE (3<<4)
|
#define EMC0TOGGLE (3<<4)
|
||||||
#define MR0R (1<<1)
|
#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_start = 0;
|
||||||
uint16_t sd_offload_partial_end = 0;
|
uint16_t sd_offload_partial_end = 0;
|
||||||
|
|
||||||
/* FIXME HACK */
|
|
||||||
volatile enum diskstates disk_state;
|
volatile enum diskstates disk_state;
|
||||||
extern volatile tick_t ticks;
|
extern volatile tick_t ticks;
|
||||||
extern snes_romprops_t romprops;
|
extern snes_romprops_t romprops;
|
||||||
|
extern volatile int reset_changed;
|
||||||
|
|
||||||
|
enum system_states {
|
||||||
|
SYS_RTC_STATUS = 0
|
||||||
|
};
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
LPC_GPIO2->FIODIR = BV(0) | BV(1) | BV(2);
|
LPC_GPIO2->FIODIR = BV(4) | BV(5);
|
||||||
LPC_GPIO1->FIODIR = 0;
|
LPC_GPIO1->FIODIR = BV(23);
|
||||||
LPC_GPIO0->FIODIR = BV(16);
|
LPC_GPIO0->FIODIR = BV(16);
|
||||||
|
|
||||||
/* connect UART3 on P0[25:26] + SSP0 on P0[15:18] + MAT3.0 on P0[10] */
|
/* 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) */
|
/* | BV(13) | BV(15) | BV(17) | BV(19) SSP1 (SD) */
|
||||||
|
|
||||||
/* pull-down CIC data lines */
|
/* 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();
|
clock_disconnect();
|
||||||
snes_init();
|
snes_init();
|
||||||
@ -72,6 +76,7 @@ led_pwm();
|
|||||||
sdn_init();
|
sdn_init();
|
||||||
printf("\n\nsd2snes mk.2\n============\nfw ver.: " VER "\ncpu clock: %d Hz\n", CONFIG_CPU_FREQUENCY);
|
printf("\n\nsd2snes mk.2\n============\nfw ver.: " VER "\ncpu clock: %d Hz\n", CONFIG_CPU_FREQUENCY);
|
||||||
printf("PCONP=%lx\n", LPC_SC->PCONP);
|
printf("PCONP=%lx\n", LPC_SC->PCONP);
|
||||||
|
|
||||||
file_init();
|
file_init();
|
||||||
cic_init(0);
|
cic_init(0);
|
||||||
/* setup timer (fpga clk) */
|
/* setup timer (fpga clk) */
|
||||||
@ -197,22 +202,35 @@ printf("PCONP=%lx\n", LPC_SC->PCONP);
|
|||||||
/* shared mode */
|
/* shared mode */
|
||||||
set_mcu_ovr(0);
|
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");
|
printf("SNES GO!\n");
|
||||||
snes_reset(1);
|
snes_reset(1);
|
||||||
delay_ms(1);
|
delay_ms(1);
|
||||||
snes_reset(0);
|
snes_reset(0);
|
||||||
|
|
||||||
uint8_t cmd = 0;
|
uint8_t cmd = 0;
|
||||||
|
uint64_t btime = 0;
|
||||||
uint32_t filesize=0;
|
uint32_t filesize=0;
|
||||||
sram_writebyte(32, SRAM_CMD_ADDR);
|
sram_writebyte(32, SRAM_CMD_ADDR);
|
||||||
printf("test sram\n");
|
printf("test sram\n");
|
||||||
while(!sram_reliable());
|
while(!sram_reliable());
|
||||||
printf("ok\n");
|
printf("ok\n");
|
||||||
|
sram_hexdump(SRAM_DIR_ADDR, 0x300);
|
||||||
//while(1) {
|
//while(1) {
|
||||||
// delay_ms(1000);
|
// delay_ms(1000);
|
||||||
// printf("Estimated SNES master clock: %ld Hz\n", get_snes_sysclk());
|
// printf("Estimated SNES master clock: %ld Hz\n", get_snes_sysclk());
|
||||||
//}
|
//}
|
||||||
//sram_hexdump(SRAM_DB_ADDR, 0x200);
|
//sram_hexdump(SRAM_DB_ADDR, 0x200);
|
||||||
//sram_hexdump(SRAM_MENU_ADDR, 0x400);
|
//sram_hexdump(SRAM_MENU_ADDR, 0x400);
|
||||||
while(!cmd) {
|
while(!cmd) {
|
||||||
@ -241,6 +259,11 @@ printf("PCONP=%lx\n", LPC_SC->PCONP);
|
|||||||
snes_reset(0);
|
snes_reset(0);
|
||||||
break;
|
break;
|
||||||
case SNES_CMD_SETRTC:
|
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 */
|
cmd=0; /* stay in loop */
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -265,6 +288,11 @@ printf("PCONP=%lx\n", LPC_SC->PCONP);
|
|||||||
sleep_ms(250);
|
sleep_ms(250);
|
||||||
sram_reliable();
|
sram_reliable();
|
||||||
printf("%s ", get_cic_statename(get_cic_state()));
|
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();
|
snes_reset_now=get_snes_reset();
|
||||||
if(snes_reset_now) {
|
if(snes_reset_now) {
|
||||||
if(!snes_reset_prev) {
|
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(0x33, rombase+0xda);
|
||||||
sram_writebyte(0x00, rombase+0xd4);
|
sram_writebyte(0x00, rombase+0xd4);
|
||||||
sram_writebyte(0xfc, rombase+0xd5);
|
sram_writebyte(0xfc, rombase+0xd5);
|
||||||
set_fpga_time(0x0020110212180500LL);
|
set_fpga_time(0x0220110301180530LL);
|
||||||
}
|
}
|
||||||
uint32_t rammask;
|
uint32_t rammask;
|
||||||
uint32_t rommask;
|
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_TX_BYTE(0x00);
|
||||||
FPGA_DESELECT();
|
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_DIR_ADDR (0xE10000L)
|
||||||
#define SRAM_CMD_ADDR (0xFF1000L)
|
#define SRAM_CMD_ADDR (0xFF1000L)
|
||||||
#define SRAM_PARAM_ADDR (0xFF1004L)
|
#define SRAM_PARAM_ADDR (0xFF1004L)
|
||||||
|
#define SRAM_STATUS_ADDR (0xFF1100L)
|
||||||
#define SRAM_MENU_SAVE_ADDR (0xFF0000L)
|
#define SRAM_MENU_SAVE_ADDR (0xFF0000L)
|
||||||
#define SRAM_SCRATCHPAD (0xFFFF00L)
|
#define SRAM_SCRATCHPAD (0xFFFF00L)
|
||||||
#define SRAM_DIRID (0xFFFFF0L)
|
#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);
|
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);
|
uint32_t calc_sram_crc(uint32_t base_addr, uint32_t size);
|
||||||
uint8_t sram_reliable(void);
|
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
|
#endif
|
||||||
|
|||||||
69
src/rtc.c
69
src/rtc.c
@ -2,12 +2,22 @@
|
|||||||
#include <arm/bits.h>
|
#include <arm/bits.h>
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "rtc.h"
|
#include "rtc.h"
|
||||||
|
#include "uart.h"
|
||||||
|
#include "timer.h"
|
||||||
|
#include "power.h"
|
||||||
|
|
||||||
rtcstate_t rtc_state;
|
rtcstate_t rtc_state;
|
||||||
|
|
||||||
#define CLKEN 0
|
#define CLKEN 0
|
||||||
#define CTCRST 1
|
#define CTCRST 1
|
||||||
|
|
||||||
|
uint8_t rtc_isvalid(void) {
|
||||||
|
if(LPC_RTC->GPREG0 == RTC_MAGIC) {
|
||||||
|
return RTC_OK;
|
||||||
|
}
|
||||||
|
return RTC_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
void rtc_init(void) {
|
void rtc_init(void) {
|
||||||
if (LPC_RTC->CCR & BV(CLKEN)) {
|
if (LPC_RTC->CCR & BV(CLKEN)) {
|
||||||
rtc_state = RTC_OK;
|
rtc_state = RTC_OK;
|
||||||
@ -23,11 +33,25 @@ void read_rtc(struct tm *time) {
|
|||||||
time->tm_hour = LPC_RTC->HOUR;
|
time->tm_hour = LPC_RTC->HOUR;
|
||||||
time->tm_mday = LPC_RTC->DOM;
|
time->tm_mday = LPC_RTC->DOM;
|
||||||
time->tm_mon = LPC_RTC->MONTH;
|
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;
|
time->tm_wday = LPC_RTC->DOW;
|
||||||
} while (time->tm_sec != LPC_RTC->SEC);
|
} 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) {
|
void set_rtc(struct tm *time) {
|
||||||
LPC_RTC->CCR = BV(CTCRST);
|
LPC_RTC->CCR = BV(CTCRST);
|
||||||
LPC_RTC->SEC = time->tm_sec;
|
LPC_RTC->SEC = time->tm_sec;
|
||||||
@ -35,17 +59,21 @@ void set_rtc(struct tm *time) {
|
|||||||
LPC_RTC->HOUR = time->tm_hour;
|
LPC_RTC->HOUR = time->tm_hour;
|
||||||
LPC_RTC->DOM = time->tm_mday;
|
LPC_RTC->DOM = time->tm_mday;
|
||||||
LPC_RTC->MONTH = time->tm_mon;
|
LPC_RTC->MONTH = time->tm_mon;
|
||||||
LPC_RTC->YEAR = time->tm_year + 1900;
|
LPC_RTC->YEAR = time->tm_year;
|
||||||
LPC_RTC->DOW = time->tm_wday;
|
LPC_RTC->DOW = calc_weekday(time);
|
||||||
LPC_RTC->CCR = BV(CLKEN);
|
LPC_RTC->CCR = BV(CLKEN);
|
||||||
|
LPC_RTC->GPREG0 = RTC_MAGIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void invalidate_rtc() {
|
||||||
|
LPC_RTC->GPREG0 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t get_fattime(void) {
|
uint32_t get_fattime(void) {
|
||||||
struct tm time;
|
struct tm time;
|
||||||
|
|
||||||
read_rtc(&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_mon) << 21 |
|
||||||
((uint32_t)time.tm_mday) << 16 |
|
((uint32_t)time.tm_mday) << 16 |
|
||||||
((uint32_t)time.tm_hour) << 11 |
|
((uint32_t)time.tm_hour) << 11 |
|
||||||
@ -56,7 +84,7 @@ uint32_t get_fattime(void) {
|
|||||||
uint64_t get_bcdtime(void) {
|
uint64_t get_bcdtime(void) {
|
||||||
struct tm time;
|
struct tm time;
|
||||||
read_rtc(&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)
|
return ((uint64_t)(time.tm_wday % 7) << 56)
|
||||||
|((uint64_t)((year / 1000) % 10) << 52)
|
|((uint64_t)((year / 1000) % 10) << 52)
|
||||||
@ -74,3 +102,34 @@ uint64_t get_bcdtime(void) {
|
|||||||
|((time.tm_sec / 10) << 4)
|
|((time.tm_sec / 10) << 4)
|
||||||
|(time.tm_sec % 10);
|
|(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
|
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
|
#ifndef RTC_H
|
||||||
@ -44,22 +41,38 @@ struct tm {
|
|||||||
uint8_t tm_hour; // 0..23
|
uint8_t tm_hour; // 0..23
|
||||||
uint8_t tm_mday; // 1..[28..31]
|
uint8_t tm_mday; // 1..[28..31]
|
||||||
uint8_t tm_mon; // 0..11
|
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
|
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
|
// 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;
|
extern rtcstate_t rtc_state;
|
||||||
|
|
||||||
void rtc_init(void);
|
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 */
|
/* Return current time in struct tm */
|
||||||
void read_rtc(struct tm *time);
|
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);
|
void set_rtc(struct tm *time);
|
||||||
|
|
||||||
|
/* Set RTC invalid */
|
||||||
|
void invalidate_rtc(void);
|
||||||
|
|
||||||
/* get current time in 60-bit BCD format (WYYYYMMDDHHMMSS) (W=DOW) */
|
/* get current time in 60-bit BCD format (WYYYYMMDDHHMMSS) (W=DOW) */
|
||||||
uint64_t get_bcdtime(void);
|
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
|
#endif
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "crc.h"
|
#include "crc.h"
|
||||||
|
#include "crc16.h"
|
||||||
#include "diskio.h"
|
#include "diskio.h"
|
||||||
#include "spi.h"
|
#include "spi.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
@ -68,12 +69,13 @@
|
|||||||
#define CARD_SDHC (1<<1)
|
#define CARD_SDHC (1<<1)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
1 DAT3/SS P0.6
|
Rev.A Rev.C
|
||||||
2 CMD/DI P0.9
|
1 DAT3/SS P0.6 P2.3
|
||||||
5 Clock P0.7
|
2 CMD/DI P0.9 P0.9
|
||||||
7 DAT0/DO P0.8
|
5 Clock P0.7 P0.7
|
||||||
8 DAT1/IRQ P1.14
|
7 DAT0/DO P0.8 P2.0
|
||||||
9 DAT2/NC P1.15
|
8 DAT1/IRQ P1.14 P2.1
|
||||||
|
9 DAT2/NC P1.15 P2.2
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* SD init procedure
|
/* SD init procedure
|
||||||
@ -197,6 +199,42 @@ static inline void wiggle_fast_pos1(void) {
|
|||||||
BITBAND(SD_CLKREG->FIOCLR, SD_CLKPIN) = 1;
|
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) {
|
static inline void wait_busy(void) {
|
||||||
while(!(BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN))) {
|
while(!(BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN))) {
|
||||||
wiggle_fast_neg1();
|
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) {
|
||||||
if(dat) wiggle_fast_neg(17);
|
#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) {
|
if(waitbusy) {
|
||||||
DBG_SD printf("waitbusy after send_cmd\n");
|
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);
|
return cmd_fast(cmd, param, crc, dat, rsp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void stream_datablock(uint8_t *buf) {
|
int stream_datablock(uint8_t *buf) {
|
||||||
// uint8_t datshift=8;
|
// uint8_t datshift=8;
|
||||||
int j=512;
|
int j=512;
|
||||||
uint8_t datdata=0;
|
uint8_t datdata=0;
|
||||||
@ -559,9 +605,14 @@ void stream_datablock(uint8_t *buf) {
|
|||||||
j--;
|
j--;
|
||||||
if(!j) break;
|
if(!j) break;
|
||||||
}
|
}
|
||||||
/* eat the crc for now */
|
#ifdef CONFIG_SD_DATACRC
|
||||||
wiggle_fast_neg(17);
|
return get_and_check_datacrc(buf-512);
|
||||||
|
#else
|
||||||
|
/* eat the crcs */
|
||||||
|
wiggle_fast_neg(17);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void send_datablock(uint8_t *buf) {
|
void send_datablock(uint8_t *buf) {
|
||||||
@ -585,7 +636,7 @@ void send_datablock(uint8_t *buf) {
|
|||||||
datshift=8;
|
datshift=8;
|
||||||
do {
|
do {
|
||||||
datshift-=4;
|
datshift-=4;
|
||||||
if(((*buf)>>datshift) & 0x8) {
|
/* if(((*buf)>>datshift) & 0x8) {
|
||||||
BITBAND(SD_DAT3REG->FIOSET, SD_DAT3PIN) = 1;
|
BITBAND(SD_DAT3REG->FIOSET, SD_DAT3PIN) = 1;
|
||||||
} else {
|
} else {
|
||||||
BITBAND(SD_DAT3REG->FIOCLR, SD_DAT3PIN) = 1;
|
BITBAND(SD_DAT3REG->FIOCLR, SD_DAT3PIN) = 1;
|
||||||
@ -604,7 +655,8 @@ void send_datablock(uint8_t *buf) {
|
|||||||
BITBAND(SD_DAT0REG->FIOSET, SD_DAT0PIN) = 1;
|
BITBAND(SD_DAT0REG->FIOSET, SD_DAT0PIN) = 1;
|
||||||
} else {
|
} else {
|
||||||
BITBAND(SD_DAT0REG->FIOCLR, SD_DAT0PIN) = 1;
|
BITBAND(SD_DAT0REG->FIOCLR, SD_DAT0PIN) = 1;
|
||||||
}
|
}*/
|
||||||
|
SD_DAT0REG->FIOPIN0 = (*buf) >> datshift;
|
||||||
wiggle_fast_pos1();
|
wiggle_fast_pos1();
|
||||||
} while (datshift);
|
} while (datshift);
|
||||||
|
|
||||||
@ -690,7 +742,17 @@ void send_datablock(uint8_t *buf) {
|
|||||||
void read_block(uint32_t address, uint8_t *buf) {
|
void read_block(uint32_t address, uint8_t *buf) {
|
||||||
if(during_blocktrans == TRANS_READ && (last_block == address-1)) {
|
if(during_blocktrans == TRANS_READ && (last_block == address-1)) {
|
||||||
//uart_putc('r');
|
//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);
|
stream_datablock(buf);
|
||||||
|
#endif
|
||||||
last_block=address;
|
last_block=address;
|
||||||
} else {
|
} else {
|
||||||
if(during_blocktrans) {
|
if(during_blocktrans) {
|
||||||
@ -703,7 +765,14 @@ void read_block(uint32_t address, uint8_t *buf) {
|
|||||||
if(!ccs) {
|
if(!ccs) {
|
||||||
address <<= 9;
|
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);
|
cmd_fast(READ_MULTIPLE_BLOCK, address, 0, buf, rsp);
|
||||||
|
#endif
|
||||||
during_blocktrans = TRANS_READ;
|
during_blocktrans = TRANS_READ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -840,6 +909,8 @@ void sdn_init(void) {
|
|||||||
BITBAND(SD_CLKREG->FIODIR, SD_CLKPIN) = 1;
|
BITBAND(SD_CLKREG->FIODIR, SD_CLKPIN) = 1;
|
||||||
BITBAND(SD_CMDREG->FIODIR, SD_CMDPIN) = 1;
|
BITBAND(SD_CMDREG->FIODIR, SD_CMDPIN) = 1;
|
||||||
BITBAND(SD_CMDREG->FIOPIN, 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")));
|
void disk_init(void) __attribute__ ((weak, alias("sdn_init")));
|
||||||
|
|
||||||
|
|||||||
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
#include "diskio.h"
|
#include "diskio.h"
|
||||||
|
|
||||||
|
#define CRC_ERROR (0xf000)
|
||||||
|
|
||||||
extern int sd_offload;
|
extern int sd_offload;
|
||||||
|
|
||||||
/* These functions are weak-aliased to disk_... */
|
/* These functions are weak-aliased to disk_... */
|
||||||
|
|||||||
@ -43,6 +43,8 @@ uint8_t initloop=1;
|
|||||||
uint32_t saveram_crc, saveram_crc_old;
|
uint32_t saveram_crc, saveram_crc_old;
|
||||||
extern snes_romprops_t romprops;
|
extern snes_romprops_t romprops;
|
||||||
|
|
||||||
|
volatile int reset_changed;
|
||||||
|
|
||||||
void prepare_reset() {
|
void prepare_reset() {
|
||||||
set_mcu_ovr(1);
|
set_mcu_ovr(1);
|
||||||
snes_reset(1);
|
snes_reset(1);
|
||||||
@ -142,7 +144,7 @@ uint8_t menu_main_loop() {
|
|||||||
sram_writebyte(0, SRAM_CMD_ADDR);
|
sram_writebyte(0, SRAM_CMD_ADDR);
|
||||||
while(!cmd) {
|
while(!cmd) {
|
||||||
if(!get_snes_reset()) {
|
if(!get_snes_reset()) {
|
||||||
while(!sram_reliable())printf("hurr\n");;
|
while(!sram_reliable())printf("hurr\n");
|
||||||
cmd = sram_readbyte(SRAM_CMD_ADDR);
|
cmd = sram_readbyte(SRAM_CMD_ADDR);
|
||||||
}
|
}
|
||||||
if(get_snes_reset()) {
|
if(get_snes_reset()) {
|
||||||
@ -155,7 +157,8 @@ uint8_t menu_main_loop() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void get_selected_name(uint8_t* fn) {
|
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);
|
printf("fd addr=%lx\n", addr);
|
||||||
sram_readblock(fn, addr + 7 + SRAM_MENU_ADDR, 256);
|
sram_readblock(fn, addr + 7 + SRAM_MENU_ADDR, 256);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,6 +7,7 @@
|
|||||||
#include "clock.h"
|
#include "clock.h"
|
||||||
#include "uart.h"
|
#include "uart.h"
|
||||||
#include "sdnative.h"
|
#include "sdnative.h"
|
||||||
|
#include "snes.h"
|
||||||
|
|
||||||
/* bit definitions */
|
/* bit definitions */
|
||||||
#define RITINT 0
|
#define RITINT 0
|
||||||
@ -15,6 +16,7 @@
|
|||||||
#define PCRIT 16
|
#define PCRIT 16
|
||||||
|
|
||||||
extern volatile int sd_changed;
|
extern volatile int sd_changed;
|
||||||
|
extern volatile int reset_changed;
|
||||||
volatile tick_t ticks;
|
volatile tick_t ticks;
|
||||||
volatile int wokefromrit;
|
volatile int wokefromrit;
|
||||||
|
|
||||||
@ -26,10 +28,15 @@ void __attribute__((weak,noinline)) SysTick_Hook(void) {
|
|||||||
void SysTick_Handler(void) {
|
void SysTick_Handler(void) {
|
||||||
ticks++;
|
ticks++;
|
||||||
static uint16_t sdch_state = 0;
|
static uint16_t sdch_state = 0;
|
||||||
|
static uint16_t reset_state = 0;
|
||||||
sdch_state = (sdch_state << 1) | SDCARD_DETECT | 0xe000;
|
sdch_state = (sdch_state << 1) | SDCARD_DETECT | 0xe000;
|
||||||
if((sdch_state == 0xf000) || (sdch_state == 0xefff)) {
|
if((sdch_state == 0xf000) || (sdch_state == 0xefff)) {
|
||||||
sd_changed = 1;
|
sd_changed = 1;
|
||||||
}
|
}
|
||||||
|
reset_state = (reset_state << 1) | get_snes_reset() | 0xe000;
|
||||||
|
if((reset_state == 0xf000) || (reset_state == 0xefff)) {
|
||||||
|
reset_changed = 1;
|
||||||
|
}
|
||||||
sdn_changed();
|
sdn_changed();
|
||||||
SysTick_Hook();
|
SysTick_Hook();
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user