Index: telechips.c =================================================================== --- telechips.c (revision 17922) +++ telechips.c (working copy) @@ -57,13 +57,175 @@ /* The following function is just test/development code */ #ifdef CPU_TCC77X + +#define nop \ + asm volatile ("nop") + +#define DEV_NAND (1<<16) + +#define NFC_BASE 0x90000000 +#define NFC_CMD (*(volatile unsigned long *)(NFC_BASE + 0x00)) +#define NFC_SADDR (*(volatile unsigned long *)(NFC_BASE + 0x0c)) +#define NFC_SDATA (*(volatile unsigned long *)(NFC_BASE + 0x40)) +#define NFC_WDATA (*(volatile unsigned long *)(NFC_BASE + 0x10)) +#define NFC_CTRL (*(volatile unsigned long *)(NFC_BASE + 0x50)) + #define NFC_DEN (1<<28) + #define NFC_16BIT (1<<26) + #define NFC_CS0 (1<<23) + #define NFC_CS1 (1<<22) + #define NFC_READY (1<<20) + #define NFC_BSIZE1 (0x00) +#define NFC_IREQ (*(volatile unsigned long *)(NFC_BASE + 0x60)) +#define NFC_RST (*(volatile unsigned long *)(NFC_BASE + 0x64)) + +#define NAND_GPIO_SET(n) GPIOC |= n +#define NAND_GPIO_CLEAR(n) GPIOC &= ~n +#define NAND_GPIO_OUT_EN(n) GPIOB_DIR |= n + +#define CS_GPIO_BIT (1<<24) /* Chip Select */ +#define WE_GPIO_BIT (1<<25) /* Write Enable */ + +#define NAND_SERIAL_MODE 0x00 +#define NAND_PARALLEL_MODE 0x01 + +static void nand_chip_select(int bank) +{ + if (bank == -1) + { + /* deselect */ + NAND_GPIO_CLEAR(CS_GPIO_BIT); + NFC_CTRL |= (NFC_CS0 | NFC_CS1); + } + else if (bank == 0) + { + NAND_GPIO_CLEAR(CS_GPIO_BIT); + NFC_CTRL = (NFC_CTRL | NFC_CS0) & ~NFC_CS1; + } + else if (bank == 1) + { + NAND_GPIO_CLEAR(CS_GPIO_BIT); + NFC_CTRL = (NFC_CTRL | NFC_CS1) & ~NFC_CS0; + } + else if (bank == 2) + { + NAND_GPIO_SET(CS_GPIO_BIT); + NFC_CTRL = (NFC_CTRL | NFC_CS0) & ~NFC_CS1; + } + else if (bank == 3) + { + NAND_GPIO_SET(CS_GPIO_BIT); + NFC_CTRL = (NFC_CTRL | NFC_CS1) & ~NFC_CS0; + } +} + +static void nand_read_id(int bank, int mode, unsigned char* id_buf) +{ + int i; + + /* First, reset */ + BCLKCTR |= DEV_NAND; /* Enable NFC bus clock */ + NFC_CTRL = (NFC_CTRL & 0xFFFFF000) | 0x151; /* Set basic timings */ + nand_chip_select(bank); /* Enable chip select */ + NFC_CTRL |= NFC_16BIT; /* Set 16-bit data bus */ + + if (mode == NAND_PARALLEL_MODE) + NFC_CMD = 0xFFFF; + else + NFC_CMD = 0x00FF; + + /* delay */ + for (i = 0; i < 16*256; i++) + nop; + + nand_chip_select(-1); /* Disable chip select */ + BCLKCTR &= ~DEV_NAND; /* Disable NFC bus clock */ + + /* Now, read the id */ + BCLKCTR |= DEV_NAND; /* Enable NFC bus clock */ + NFC_CTRL = (NFC_CTRL & 0xFFFFF000) | 0x151; /* Set basic timings */ + nand_chip_select(bank); /* Enable chip select */ + NFC_CTRL |= NFC_16BIT; /* Set 16-bit data bus */ + + if (mode == NAND_PARALLEL_MODE) + NFC_CMD = 0x9090; + else + NFC_CMD = 0x0090; + + NFC_SADDR = 0x00; + + /* delay */ + nop; nop; nop; nop; nop; nop; + nop; nop; nop; nop; nop; nop; + nop; nop; nop; nop; nop; nop; + nop; nop; nop; nop; nop; nop; + nop; nop; nop; nop; nop; nop; + + if (mode == NAND_PARALLEL_MODE) + { + id_buf[0] = NFC_SDATA; + id_buf[1] = NFC_SDATA; + id_buf[2] = NFC_SDATA; + id_buf[3] = NFC_SDATA; + id_buf[4] = NFC_SDATA; + } + else + { + id_buf[0] = NFC_SDATA & 0xFF; + id_buf[1] = NFC_SDATA & 0xFF; + id_buf[2] = NFC_SDATA & 0xFF; + id_buf[3] = NFC_SDATA & 0xFF; + id_buf[4] = NFC_SDATA & 0xFF; + } + + nand_chip_select(-1); /* Disable chip select */ + BCLKCTR &= ~DEV_NAND; /* Disable NFC bus clock */ +} + +int nand_init(void) +{ + /* From the Sansa C100 firmware */ + CSCFG2 = 0x318a8010; + + GPIOC_DIR |= 0x2000000; /* output mode */ + GPIOC_FUNC &= ~0x2000000; /* normal IO port */ + GPIOC_FUNC |= 0x1; + + BCLKCTR |= DEV_NAND; /* Enable NFC bus clock */ + NFC_RST = 0; /* reset */ + + /* Default config */ + NFC_CTRL = NFC_DEN | + NFC_CS0 | + NFC_CS1 | + NFC_BSIZE1 | + (2 << 4) | /* pw = 2 */ + (1 << 0); /* hold = 1 */ + +#if 0 + NFC_IREQ = 0x77; /* Clear interrupts */ + CREQ = CREQ_ND; + IRQSEL |= IRQSEL_ND; /* Set NFC as IRQ interrupt */ + TMODE = uTMODE | 0x100000; /* Level type for NFC interrupt */ +#endif + + BCLKCTR |= DEV_NAND; /* Disable NFC bus clock */ + + return true; +} + void show_debug_screen(void) { int button; int power_count = 0; int count = 0; bool do_power_off = false; - + unsigned char id_buf[8]; + + /* Read chip id from bank 0 */ + nand_init(); + nand_read_id(0, NAND_SERIAL_MODE, id_buf); + + /*lcd_puts_scroll(0,0,"this is a very long line to test scrolling");*/ while(!do_power_off) { @@ -87,7 +249,10 @@ else{ _backlight_on(); } - + + printf("NAND: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x", + id_buf[0],id_buf[1],id_buf[2],id_buf[3],id_buf[4]); + /*printf("Btn: 0x%08x",button); printf("Tick: %d",current_tick); printf("GPIOA: 0x%08x",GPIOA);