firmware: adjustments for Mk.II Rev.C; enable timesetting from SNES menu

This commit is contained in:
ikari
2011-03-14 01:45:34 +01:00
parent 9af83658e7
commit bfe9a91d07
34 changed files with 2811 additions and 2564 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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