diff --git a/Makefile b/Makefile index 4a6653d..52d6f2d 100644 --- a/Makefile +++ b/Makefile @@ -50,3 +50,4 @@ clean: rm -f *.o boot-programs/*.o $(BUILT_SOURCES) $(ARCH_CLEAN_FILES) .PHONY: clean +.PRECIOUS: iris.hh boot-programs/crt0.o diff --git a/boot-programs/buzzer.ccp b/boot-programs/buzzer.ccp index c13efed..28ed54a 100644 --- a/boot-programs/buzzer.ccp +++ b/boot-programs/buzzer.ccp @@ -27,9 +27,9 @@ class DevBuzzer: public: DevBuzzer (): is_beeping = false - gpio_as_pwm4 () tcu_stop_counter (pwm) - tcu_select_extalclk (pwm) + //tcu_select_extalclk (pwm) + tcu_select_pclk (pwm) tcu_select_clk_div64 (pwm) tcu_enable_pwm_output (pwm) void stop (): @@ -54,7 +54,6 @@ enum codes: BUZZER = 32 Kernel::Num start (): - map_gpio () map_tcu () DevBuzzer buzzer diff --git a/boot-programs/lcd.ccp b/boot-programs/lcd.ccp index fe0d27e..1314b2e 100644 --- a/boot-programs/lcd.ccp +++ b/boot-programs/lcd.ccp @@ -24,12 +24,12 @@ __asm__ volatile (".section .rodata\n.globl charset\ncharset:\n.incbin \"boot-pr // charset is really the first character in the array. Its address is used as the start of the array. extern unsigned char const charset[127-32][6] -#define assert(x) do { while (!(x)) kdebug ("assertion failed " #x); } while (0) +#define assert(x) do { if (!(x)) { kdebug ("assertion failed " #x); while (true) {} } } while (0) #if defined (TRENDTAC) static unsigned h = 800, v = 480, fps = 60, Bpp = 2 #elif defined (NANONOTE) -static unsigned h = 320, v = 240, fps = 70, Bpp = 4 +static unsigned h = 320, v = 240, fps = 60, Bpp = 4 #else #error unknown board #endif @@ -68,7 +68,7 @@ enum spi_reg: BACKLIGHT2 = 0x08 SYNC = 0x0b POLARITY = 0x0c - CONTRAST_B = 0x0d + CONTRAST_RGB = 0x0d SUB_CONTRAST_R = 0x0e SUB_BRIGHTNESS_R= 0x0f SUB_CONTRAST_B = 0x10 @@ -86,9 +86,9 @@ enum spi_reg: FB = 0xb1 static void write_reg (unsigned reg, unsigned val): + unsigned value = (reg << 8) | (val & 0xff) gpio_clear (SP_PORT, 1 << SPEN) udelay (1) - unsigned value = (reg << 8) | (val & 0xff) for unsigned i = 0; i < 16; ++i, value <<= 1: gpio_clear (SP_PORT, 1 << SPCK) if value & 0x8000: @@ -97,7 +97,7 @@ static void write_reg (unsigned reg, unsigned val): gpio_clear (SP_PORT, 1 << SPDA) udelay (4) gpio_set (SP_PORT, 1 << SPCK) - udelay (1) + udelay (4) gpio_set (SP_PORT, 1 << SPEN) udelay(4) #endif @@ -111,7 +111,7 @@ static void reset (): unsigned hsync = 80, hpre = 80, hpost = 0 // One clock pulse per pixel. - unsigned extra = 0 + unsigned cpp = 1 // Bits per pixel. unsigned bpp = LCD_CTRL_BPP_16 // Configuration. @@ -120,39 +120,30 @@ static void reset (): unsigned cfg = MODE_TFT_GEN | VSYNC_N #elif defined (NANONOTE) // Note that the sync pulse is part of the pre-display region. + // Horizontal timings. + unsigned hsync = 1, hpre = 141, hpost = 273 // Vertical timings. unsigned vsync = 1, vpre = 21, vpost = 2 - // Horizontal timings. - unsigned hsync = 1, hpre = 70, hpost = 686 - - // 3 bytes per pixel, so for the display area 2 extra clocks are sent. - unsigned extra = 2 + // 3 clocks per pixel. + unsigned cpp = 3 // Bits per pixel. unsigned bpp = LCD_CTRL_BPP_18_24 // Configuration. unsigned cfg = LCD_CFG_MODE_SERIAL_TFT | LCD_CFG_HSP | LCD_CFG_VSP // Set up SPI pins. - gpio_as_output(SP_PORT, (1 << SPEN) | (1 << SPCK) | (1 << SPDA)) + gpio_as_output (SP_PORT, (1 << SPEN) | (1 << SPCK) | (1 << SPDA)) gpio_set (SP_PORT, (1 << SPEN) | (1 << SPCK)) #else #error unknown board #endif // Note that the sync pulse is part of the pre-display region. - unsigned vps = 0, vpe = vps + vsync, vds = vps + vpre, vde = vds + v, vt = vde + vpost - unsigned hps = 0, hpe = hps + hsync, hds = hps + hpre, hde = hds + h, ht = hde + hpost - - LCD_CFG = cfg - LCD_HSYNC = (hps << 16) | hpe - LCD_VSYNC = (vps << 16) | vpe - LCD_VAT = (ht << 16) | vt - LCD_DAH = (hds << 16) | hde - LCD_DAV = (vds << 16) | vde - LCD_CTRL = (bpp << LCD_CTRL_BPP_BIT) | LCD_CTRL_BST_16 + unsigned vpe = vsync, vds = vpre, vde = vds + v, vt = vde + vpost + unsigned hpe = hsync, hds = hpre, hde = hds + cpp * h, ht = hde + hpost cpm_stop_lcd () - unsigned pixclock = fps * (ht + extra * h) * vt + unsigned pixclock = fps * ht * vt #if defined (TRENDTAC) unsigned pllout = cpm_get_pllout () @@ -165,30 +156,47 @@ static void reset (): CPM_CFCR |= CPM_CFCR_UPE #elif defined (NANONOTE) unsigned val = cpm_get_pllout2 () / pixclock - 1 + kdebug ("clock: ") kdebug_num (val) kdebug ("\n") - assert (val < 0x400) - cpm_set_pixdiv (val); + //assert (val < 0x400) + //cpm_set_pixdiv (val) + //cpm_set_pixdiv (12) - val = cpm_get_pllout () / (pixclock * 3) + val = cpm_get_pllout2 () / (pixclock * 3) - 1 + kdebug ("clock: ") + kdebug_num (val) + kdebug ("\n") assert (val < 0x20) - cpm_set_ldiv (val) + //cpm_set_ldiv (val) // Update dividers. - CPM_CPCCR |= CPM_CPCCR_CE + //CPM_CPCCR |= CPM_CPCCR_CE + #else + #error "Unknown board" #endif cpm_start_lcd () - LCD_DA0 = physical_descriptor - lcd_set_ena () - //lcd_enable_eof_intr () #ifdef NANONOTE - // Reset registers. - write_reg (BACKLIGHT1, 0) + // Reset the controller. + //write_reg (BACKLIGHT1, 0x1e) // Enable display. write_reg (BACKLIGHT1, 0x5f) + // Set data to rgbrgbrgb input, with a delta color filter. + write_reg (COLOR, 0x01) #endif + LCD_CTRL = (bpp << LCD_CTRL_BPP_BIT) | LCD_CTRL_BST_16 + LCD_CFG = cfg + LCD_HSYNC = hpe + LCD_VSYNC = vpe + LCD_VAT = (ht << 16) | vt + LCD_DAH = (hds << 16) | hde + LCD_DAV = (vds << 16) | vde + LCD_DA0 = physical_descriptor + LCD_CTRL = (bpp << LCD_CTRL_BPP_BIT) | LCD_CTRL_BST_16 | LCD_CTRL_ENA + //lcd_enable_eof_intr () + static void putchar (unsigned x, unsigned y, unsigned ch, unsigned fg = 0xffff, unsigned bg = 0x0000): if ch < 32 || ch > 126: ch = 127 @@ -239,7 +247,9 @@ static void log_msg (): log_char ('\n') enum captype: + #ifdef TRENDTAC LOG + #endif SET_EOF_CB Kernel::Num start (): @@ -266,6 +276,7 @@ Kernel::Num start (): #if defined (TRENDTAC) LCD_FRAMEBUFFER_BASE[y * h + x] = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3) #elif defined (NANONOTE) + LCD_FRAMEBUFFER_BASE[(y * h + x) * Bpp + 3] = 0 LCD_FRAMEBUFFER_BASE[(y * h + x) * Bpp + 2] = r LCD_FRAMEBUFFER_BASE[(y * h + x) * Bpp + 1] = g LCD_FRAMEBUFFER_BASE[(y * h + x) * Bpp + 0] = b @@ -284,8 +295,8 @@ Kernel::Num start (): __asm__ volatile ("lw $a0, %0\ncache 0x15, 0($a0)" :: "m"(dptr) : "memory", "a0") reset () - Kernel::Cap logcap = Kernel::my_receiver.create_capability (LOG) #if defined (TRENDTAC) + Kernel::Cap logcap = Kernel::my_receiver.create_capability (LOG) __asm__ volatile ("li $a0, 1\nlw $a1, %0\nbreak" :: "m"(logcap.code): "a0", "a1", "memory") #endif @@ -310,9 +321,11 @@ Kernel::Num start (): reply.invoke () Kernel::free_cap (reply) break + #ifdef TRENDTAC case LOG: log_char (Kernel::recv.data[0].l) break + #endif default: log_char ('~') break diff --git a/boot-programs/udc.ccp b/boot-programs/udc.ccp index 8af41e6..7b46b32 100644 --- a/boot-programs/udc.ccp +++ b/boot-programs/udc.ccp @@ -16,6 +16,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +#include "iris.hh" #include "devices.hh" #define ARCH #include "arch.hh" @@ -153,6 +154,7 @@ void Udc::init (): configuration = 0 size = 0 // exit suspend mode by reading the interrupt register. + cpm_start_udc () unsigned i = UDC_INTRUSB // reset all pending endpoint interrupts. i = UDC_INTRIN @@ -331,6 +333,7 @@ enum pdata: Kernel::Num start (): map_udc () map_gpio () + map_cpm () Udc udc udc.init () diff --git a/devices.hhp b/devices.hhp index 2dfcbd9..9c32f46 100644 --- a/devices.hhp +++ b/devices.hhp @@ -89,13 +89,13 @@ struct Device : public Kernel::Cap: Kernel::Cap create_user (Kernel::Memory storage): iocall (storage, CAP_MASTER_DIRECT | CREATE_USER) return Kernel::get_arg () - // Destroy a user. It must not be active. + // Destroy a user. It is made inactive if it was active. void destroy_user (Kernel::Cap user): ocall (user, CAP_MASTER_DIRECT | DESTROY_USER) // Make user inactive. void unuse (Kernel::Cap user): ocall (user, CAP_MASTER_DIRECT | UNUSE) - // Make user active. + // Make user active. It makes the previous active user inactive. void use (Kernel::Cap user): ocall (user, CAP_MASTER_DIRECT | USE) @@ -142,8 +142,10 @@ struct Keyboard : public Kernel::Cap: // Set the event callback. Currently pressed keys emit a key press event to the new callback immediately. void set_cb (Kernel::Cap cb): ocall (cb, CAP_MASTER_DIRECT | SET_CB) + // Get the number of keys on the keyboard. unsigned get_num_keys (): return call (CAP_MASTER_DIRECT | GET_NUM_KEYS).l + // Get the keycodes for the keys. The reply sends 4 key codes (32 bit each). void get_keys (unsigned first): call (CAP_MASTER_DIRECT | GET_KEYS, first) @@ -154,7 +156,7 @@ struct Buzzer : public Kernel::Cap: BEEP = Keyboard::ID STOP ID - // Emit a beep of specified frequency, time and volume. Volume may not be supported. + // Emit a beep of specified frequency, time and volume. Volume may not be supported. If an other beep is in progress, it is aborted. void beep (unsigned freq, unsigned ms, unsigned volume, Kernel::Cap cb = Kernel::Cap ()): ocall (cb, Kernel::Num (CAP_MASTER_DIRECT | BEEP, volume), Kernel::Num (freq, ms)) // Abort current beep, if any. @@ -192,8 +194,9 @@ struct Display : public Kernel::Cap: // File system interface. -// filesystem-related interfaces: directory, stream, seekable, mappable. -// Normal files implement at least stream or seekable file. Directories implement directory. +// filesystem-related interfaces: directory, stream, seekable. +// Normal files implement stream and/or seekable. Directories implement directory. +// Seekable is not a class, it is identical to [W]String. // Directory interface. struct Directory : public Kernel::Cap: @@ -201,12 +204,8 @@ struct Directory : public Kernel::Cap: enum request: GET_SIZE = Display::ID GET_NAME - GET_FILE + GET_FILE_RO GET_FILE_INFO - CREATE_FILE - DELETE_FILE - LOCK - UNLOCK LOCK_RO UNLOCK_RO ID @@ -218,12 +217,31 @@ struct Directory : public Kernel::Cap: icall (CAP_MASTER_DIRECT | GET_NAME, idx) return Kernel::get_arg () // Get the file. + Kernel::Cap get_file_ro (Kernel::Num idx): + icall (CAP_MASTER_DIRECT | GET_FILE_RO, idx) + return Kernel::get_arg () + // Get file info. TODO: define possible types. + Kernel::Num get_file_info (Kernel::Num idx, unsigned type): + return icall (Kernel::Num (CAP_MASTER_DIRECT | GET_FILE_INFO, type), idx) + // Lock the directory for reading. Multiple read locks can exist simultaneously, but no write lock can be present. + void lock_ro (): + call (CAP_MASTER_DIRECT | LOCK_RO) + // Release a read-only lock. Write operations can only be done when the directory is locked. + void unlock_ro (): + call (CAP_MASTER_DIRECT | UNLOCK_RO) +struct WDirectory : public Directory: + WDirectory (Kernel::Cap c = Kernel::Cap ()) : Directory (c): + enum request: + GET_FILE = Directory::ID + CREATE_FILE + DELETE_FILE + LOCK + UNLOCK + ID + // Get the file. Kernel::Cap get_file (Kernel::Num idx): icall (CAP_MASTER_DIRECT | GET_FILE, idx) return Kernel::get_arg () - // Get file info. This returns the same information as file_get_info, without opening the file. - Kernel::Num get_file_info (Kernel::Num idx, unsigned type): - return icall (Kernel::Num (CAP_MASTER_DIRECT | GET_FILE_INFO, type), idx) // Create a new file. After this, any index may map to a different file. Kernel::Cap create_file (String name): icall (CAP_MASTER_DIRECT | CREATE_FILE) @@ -237,55 +255,26 @@ struct Directory : public Kernel::Cap: // Unlock the directory. Write operations can only be done when the directory is locked. void unlock (): call (CAP_MASTER_DIRECT | LOCK) - // Lock the directory for reading. Multiple read locks can exist simultaneously, but no write lock can be present. - void lock_ro (): - call (CAP_MASTER_DIRECT | LOCK) - // Unlock the directory. Write operations can only be done when the directory is locked. - void unlock_ro (): - call (CAP_MASTER_DIRECT | LOCK) // Stream interface. struct Stream : public Kernel::Cap: Stream (Kernel::Cap c = Kernel::Cap ()) : Kernel::Cap (c): enum request: - READ = Directory::ID + READ = WDirectory::ID WRITE ID // Try to read size bytes. Returns the number of bytes successfully read. - Kernel::Num read (Kernel::Num size): - return icall (CAP_MASTER_DIRECT | READ, size) + Kernel::Num read (Kernel::Num size, bool block): + return icall (Kernel::Num (CAP_MASTER_DIRECT | READ, block), size) // Try to write size bytes. Returns the number of bytes successfully written. Kernel::Num write (String s, Kernel::Num size): return ocall (s, CAP_MASTER_DIRECT | WRITE, size) -// Seekable file interface. -struct Seekable : public Kernel::Cap: - Seekable (Kernel::Cap c = Kernel::Cap ()) : Kernel::Cap (c): - enum request: - READ = Stream::ID - WRITE - TRUNCATE - ID - // Try to read size bytes from position idx. Returns the number of bytes successfully read. - Kernel::Num read (Kernel::Num idx, unsigned size): - return icall (Kernel::Num (CAP_MASTER_DIRECT | READ, size), idx) - // Try to write size bytes at position idx; the file is extended with zeroes if the write is past the end. Returns the number of bytes successfully written. - Kernel::Num write (Kernel::Num idx, String s): - return ocall (s, CAP_MASTER_DIRECT | WRITE, idx) - // Truncate file to size idx. The file is extended with zeroes if it gets longer. - void truncate (Kernel::Num idx): - call (CAP_MASTER_DIRECT | TRUNCATE, idx) - -// Mappable file interface. -struct Mappable : public Seekable: - Mappable (Kernel::Cap c = Kernel::Cap ()) : Seekable (c): - // TODO: to be designed. - // Block device interface. -struct Block_device : public Mappable: - Block_device (Kernel::Cap c = Kernel::Cap ()) : Mappable (c): +struct Block_device : public WString: + Block_device (Kernel::Cap c = Kernel::Cap ()) : WString (c): // TODO: to be designed. @@ -295,6 +284,5 @@ struct Block_device : public Mappable: // Pointer interface. (Only movement; buttons follow keyboard interface.) // Network interface. // Camera interface. -// Terminal interfaces. #endif diff --git a/iris.hhp b/iris.hhp index dc8df02..f1ea109 100644 --- a/iris.hhp +++ b/iris.hhp @@ -487,7 +487,7 @@ namespace Kernel: my_thread.call (CAP_MASTER_DIRECT | Thread::DBG_SEND, Num (code, bits)) inline void reboot (): my_thread.call (CAP_MASTER_DIRECT | Thread::PRIV_REBOOT) - inline void panic (unsigned code): + inline void kernel_panic (unsigned code): my_thread.call (CAP_MASTER_DIRECT | Thread::PRIV_PANIC, code) void Receiver::sleep (unsigned value): diff --git a/kernel.hhp b/kernel.hhp index 4d31a23..6f0ef37 100644 --- a/kernel.hhp +++ b/kernel.hhp @@ -21,7 +21,6 @@ // Include definitions which are shared with user space. #define __KERNEL__ -#include "iris.hh" // Normally define all variables in this file as extern. // Exactly once (in data.ccp), EXTERN is predefined empty. @@ -38,6 +37,20 @@ struct kCapability struct kCaps struct kMemory +// Some functions which must be defined early. +extern "C": + #ifndef NDEBUG + void dbg_log_char (unsigned ch) + void dbg_log (char const *str) + void dbg_log_num (unsigned num, unsigned digits = 8) + #else + #define dbg_log_char(x) do {} while (0) + #define dbg_log(x) do {} while (0) + #define dbg_log_num(n) do {} while (0) + #endif + +#include "iris.hh" + typedef kPage *kPageP typedef kThread *kThreadP typedef kMessage *kMessageP @@ -217,9 +230,6 @@ extern "C": #ifndef NDEBUG EXTERN Kernel::Num dbg_code EXTERN kCapRef dbg_cap - void dbg_log_char (unsigned ch) - void dbg_log (char const *str) - void dbg_log_num (unsigned num, unsigned digits = 8) void dbg_send (unsigned num, unsigned bits) void check (unsigned num, char const *msg) #define dbg_check() ::check (__LINE__, __FILE__) @@ -229,9 +239,6 @@ extern "C": #define dpanic(n, msg) panic (n, msg) #define dbg_print() top_memory.print (__LINE__, 0) #else - #define dbg_log_char(x) do {} while (0) - #define dbg_log(x) do {} while (0) - #define dbg_log_num(n) do {} while (0) #define dbg_send(n, m) do {} while (0) #define check (n, x) do {} while (0) #define dpanic(n, x) do {} while (0) diff --git a/memory.ccp b/memory.ccp index 757f3a6..492a884 100644 --- a/memory.ccp +++ b/memory.ccp @@ -6,6 +6,8 @@ extern unsigned _end static void clear_page (unsigned page, unsigned num = 1): for unsigned i = 0; i < (num << (PAGE_BITS - 2)); ++i: ((unsigned *)page)[i] = 0 + if *((unsigned *)page) != 0 || ((unsigned *)page)[(num << (PAGE_BITS - 2)) - 1] != 0: + dpanic (0, "clear_page didn't work") #if 0 @@ -48,7 +50,7 @@ unsigned init_memory (unsigned mem): first_free = (kFreePages *)(((unsigned)&_end + ~PAGE_MASK) & PAGE_MASK) first_free->prev = NULL first_free->next = NULL - first_free->num = ((mem & PAGE_MASK) - ((unsigned)first_free - 0x80000000)) >> PAGE_BITS + first_free->num = ((mem & PAGE_MASK) - ((unsigned)first_free & ~0xc0000000)) >> PAGE_BITS return first_free->num unsigned phys_alloc (unsigned num): diff --git a/mips/nanonote/Makefile.arch b/mips/nanonote/Makefile.arch index 54aacbd..f060ca0 100644 --- a/mips/nanonote/Makefile.arch +++ b/mips/nanonote/Makefile.arch @@ -45,13 +45,13 @@ nanonote-boot: mips/nanonote/nanonote-boot.cc mips/nanonote/sdram-setup.raw mips/nanonote/sdram-setup.elf: mips/nanonote/sdram-setup.ld mips/nanonote/sdram-setup.elf: LDFLAGS = --omagic -T mips/nanonote/sdram-setup.ld +mips/nanonote/threadlist.o: $(addsuffix .elf,$(boot_threads)) mips/boot.o: TARGET_FLAGS = -DMEMORY_SIZE="32 << 20" -mips/entry.o: $(addsuffix .elf,$(boot_threads)) mips/init.o: TARGET_FLAGS = -I/usr/include $(addsuffix .elf,$(boot_threads)): TARGET_FLAGS = -I. $(addsuffix .elf,$(boot_threads)): LDFLAGS = -EL $(addprefix boot-programs/,$(addsuffix .cc,$(boot_threads))): devices.hh keys.hh -lcd: boot-programs/charset.data +lcd.elf: boot-programs/charset.data boot-programs/charset.data: boot-programs/charset $< > $@ @@ -64,3 +64,5 @@ iris.elf: mips/entry.o $(subst .cc,.o,$(iris_sources)) mips/nanonote/threadlist. $(LD) $(LDFLAGS) $^ -o $@ ARCH_CLEAN_FILES = $(boot_sources) $(addsuffix .elf,$(boot_threads)) $(arch_headers) devices.hh keys.hh mips/*.o mips/nanonote/*.o boot-programs/charset.data iris.elf iris.raw mips/nanonote/sdram-setup.elf mips/nanonote/sdram-setup.raw + +.PRECIOUS: mips/arch.hh mips/nanonote/jz4740.hh mips/nanonote/board.hh diff --git a/mips/nanonote/board.ccp b/mips/nanonote/board.ccp index e66e70e..6dfe97d 100644 --- a/mips/nanonote/board.ccp +++ b/mips/nanonote/board.ccp @@ -21,14 +21,21 @@ #include "kernel.hh" void board_init (): + unsigned cpm_uhccdr = CPM_UHCCDR + unsigned cpm_cpccr = CPM_CPCCR + unsigned cpm_cppcr = CPM_CPPCR pll_init () - cpm_start_all () + cpm_stop_all () + cpm_start_uart0 () + cpm_start_tcu () + cpm_start_lcd () gpio_as_uart0 () gpio_as_sdram_16bit () gpio_as_nand () gpio_as_aic () gpio_as_msc () gpio_as_lcd_16bit () + gpio_as_pwm4 () // Set up memory. setup_sdram () // Use some gpio pins for lcd. @@ -38,6 +45,7 @@ void board_init (): gpio_as_output (3, 1 << 27) // Set up keyboard: this breaks uart receive. gpio_as_gpio (3, 0x05fc0000) + // Set up timed interrupts. tcu_stop_counter (0) tcu_select_extalclk (0) tcu_select_clk_div4 (0) @@ -62,6 +70,10 @@ void board_init (): UART0_FCR = UARTFCR_UUE | UARTFCR_FE | UARTFCR_RFLS | UARTFCR_TFLS dbg_code.l = 1 dbg_log ("Serial port initialized\n") + dbg_log_num (CPM_CPCCR) + dbg_log ("+") + dbg_log_num (CPM_CPPCR) + dbg_log ("\n") void arch_reboot (): // Wait for serial port to be done. diff --git a/mips/nanonote/jz4740.hhp b/mips/nanonote/jz4740.hhp index d9400a4..e0ae8ba 100644 --- a/mips/nanonote/jz4740.hhp +++ b/mips/nanonote/jz4740.hhp @@ -2346,18 +2346,16 @@ static void gpio_disable_pull (unsigned p, unsigned pins): // CPM //************************************************************************** static void pll_init (): - // The cpu clock is set to 252 MHz - unsigned const cpu_clock = 252000000 - // The usb clock must be 48 MHz - unsigned const usb_clock = 48000000 - // ssi clock must be 12 MHz, therefore it is taken directly from JZ_EXTAL, not from divided pll output. - - // USB clock must be 48 MHz. - CPM_UHCCDR = (cpu_clock / 2) / usb_clock - 1 - // Set up dividers; see documentation for the meaning of all the values. - CPM_CPCCR = CPM_CPCCR_CLKOEN | CPM_CPCCR_UCS | (0 << CPM_CPCCR_CDIV_BIT) | (2 << CPM_CPCCR_HDIV_BIT) | (2 << CPM_CPCCR_PDIV_BIT) | (2 << CPM_CPCCR_MDIV_BIT) | (3 << CPM_CPCCR_LDIV_BIT) - // Configure the pll frequency to 252 MHz. + // The cpu clock frequency + //unsigned const cpu_clock = 336000000 + unsigned const cpu_clock = 210000000 + unsigned const pixclock = 27000000 + // Configure the pll frequency to cpu_clock. CPM_CPPCR = ((cpu_clock * 2 / JZ_EXTAL - 2) << CPM_CPPCR_PLLM_BIT) | (0 << CPM_CPPCR_PLLN_BIT) | (0 << CPM_CPPCR_PLLOD_BIT) | (0x20 << CPM_CPPCR_PLLST_BIT) | CPM_CPPCR_PLLEN + // Set up dividers; see documentation for the meaning of all the values. + // USB clock seems to work when bypassing the pll. (even though it must be 48 MHz according to the datasheet.) + CPM_CPCCR = CPM_CPCCR_CLKOEN | (0 << CPM_CPCCR_CDIV_BIT) | (2 << CPM_CPCCR_HDIV_BIT) | (2 << CPM_CPCCR_PDIV_BIT) | (2 << CPM_CPCCR_MDIV_BIT) | (3 << CPM_CPCCR_LDIV_BIT) | CPM_CPCCR_CE | CPM_CPCCR_PCS + CPM_LPCDR = (cpu_clock / pixclock) - 1 static unsigned cpm_get_pllm (): return (CPM_CPPCR & CPM_CPPCR_PLLM_MASK) >> CPM_CPPCR_PLLM_BIT @@ -3584,7 +3582,7 @@ static void cim_enable_nongated_clock_mode (): #define rtc_set_scratch_pattern(n) (RTC_HSPR = n ) - +#ifdef __KERNEL__ static void setup_sdram (): // SDRAM BANK Number: 1, 2 unsigned CONFIG_NR_DRAM_BANKS = 1 @@ -3682,6 +3680,31 @@ static void setup_sdram (): // Set back to basic DMCR value EMC_DMCR = dmcr | EMC_DMCR_RFSH | EMC_DMCR_MRSET - + #if 0 + EMC_SMCR (0) = 0x00000080 + EMC_SMCR (1) = 0x094c4400 + EMC_SMCR (2) = 0x0fff7700 + EMC_SMCR (3) = 0x0fff7700 + EMC_SMCR (4) = 0x0fff7700 + EMC_SACR (0) = 0x1cfc + EMC_SACR (1) = 0x18fc + EMC_SACR (2) = 0x14fc + EMC_SACR (3) = 0x0cfc + EMC_SACR (4) = 0x08fc + EMC_DMCR = 0x85aa3211 + EMC_RTCSR = 0x83 + EMC_RTCOR = 0x1f + #endif + for unsigned i = 0; i < 5; ++i: + dbg_log ("memory: ") + dbg_log_num (EMC_SMCR (i), 8) + dbg_log (",") + dbg_log_num (EMC_SACR (i), 8) + dbg_log (";") + dbg_log_num (EMC_RTCSR, 8) + dbg_log (",") + dbg_log_num (EMC_RTCOR, 8) + dbg_log ("\n") +#endif #endif diff --git a/mips/nanonote/nanonote-boot.ccp b/mips/nanonote/nanonote-boot.ccp index da13740..9448fc2 100644 --- a/mips/nanonote/nanonote-boot.ccp +++ b/mips/nanonote/nanonote-boot.ccp @@ -135,7 +135,7 @@ nanonote::nanonote (unsigned skip): // Get info will reset the device if it has already booted into Iris. get_cpu_info () usb_close (handle) - sleep (1) + sleep (5) if !find_device (skip): std::cerr << "unable to find NanoNote device again.\n"; throw "unable to find NanoNote device again"; diff --git a/mips/nanonote/sdram-setup.ccp b/mips/nanonote/sdram-setup.ccp index 4d52715..3b6ee7f 100644 --- a/mips/nanonote/sdram-setup.ccp +++ b/mips/nanonote/sdram-setup.ccp @@ -18,6 +18,9 @@ // This runs like the kernel. In particular, it doesn't want userspace declarations. #define __KERNEL__ +#define dbg_log(x) do {} while (0) +#define dbg_log_char(x) do {} while (0) +#define dbg_log_num(...) do {} while (0) #include "jz4740.hh" asm volatile (".set noreorder\n" diff --git a/mips/nanonote/threadlist.S b/mips/nanonote/threadlist.S index 4c69962..e970c7b 100644 --- a/mips/nanonote/threadlist.S +++ b/mips/nanonote/threadlist.S @@ -25,7 +25,7 @@ thread0: .balign 0x1000 thread1: - .incbin "udc.elf" + .incbin "lcd.elf" .balign 0x1000 thread2: @@ -41,7 +41,7 @@ thread4: .balign 0x1000 thread5: - .incbin "lcd.elf" + .incbin "udc.elf" thread6: