1
0
mirror of git://projects.qi-hardware.com/iris.git synced 2024-12-29 20:04:34 +02:00

Looking for the lcd problem and more

This commit is contained in:
Bas Wijnen 2009-12-11 09:43:42 +01:00
parent a383b3ffd3
commit cf496f031f
14 changed files with 166 additions and 113 deletions

View File

@ -50,3 +50,4 @@ clean:
rm -f *.o boot-programs/*.o $(BUILT_SOURCES) $(ARCH_CLEAN_FILES) rm -f *.o boot-programs/*.o $(BUILT_SOURCES) $(ARCH_CLEAN_FILES)
.PHONY: clean .PHONY: clean
.PRECIOUS: iris.hh boot-programs/crt0.o

View File

@ -27,9 +27,9 @@ class DevBuzzer:
public: public:
DevBuzzer (): DevBuzzer ():
is_beeping = false is_beeping = false
gpio_as_pwm4 ()
tcu_stop_counter (pwm) tcu_stop_counter (pwm)
tcu_select_extalclk (pwm) //tcu_select_extalclk (pwm)
tcu_select_pclk (pwm)
tcu_select_clk_div64 (pwm) tcu_select_clk_div64 (pwm)
tcu_enable_pwm_output (pwm) tcu_enable_pwm_output (pwm)
void stop (): void stop ():
@ -54,7 +54,6 @@ enum codes:
BUZZER = 32 BUZZER = 32
Kernel::Num start (): Kernel::Num start ():
map_gpio ()
map_tcu () map_tcu ()
DevBuzzer buzzer DevBuzzer buzzer

View File

@ -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. // 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] 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) #if defined (TRENDTAC)
static unsigned h = 800, v = 480, fps = 60, Bpp = 2 static unsigned h = 800, v = 480, fps = 60, Bpp = 2
#elif defined (NANONOTE) #elif defined (NANONOTE)
static unsigned h = 320, v = 240, fps = 70, Bpp = 4 static unsigned h = 320, v = 240, fps = 60, Bpp = 4
#else #else
#error unknown board #error unknown board
#endif #endif
@ -68,7 +68,7 @@ enum spi_reg:
BACKLIGHT2 = 0x08 BACKLIGHT2 = 0x08
SYNC = 0x0b SYNC = 0x0b
POLARITY = 0x0c POLARITY = 0x0c
CONTRAST_B = 0x0d CONTRAST_RGB = 0x0d
SUB_CONTRAST_R = 0x0e SUB_CONTRAST_R = 0x0e
SUB_BRIGHTNESS_R= 0x0f SUB_BRIGHTNESS_R= 0x0f
SUB_CONTRAST_B = 0x10 SUB_CONTRAST_B = 0x10
@ -86,9 +86,9 @@ enum spi_reg:
FB = 0xb1 FB = 0xb1
static void write_reg (unsigned reg, unsigned val): static void write_reg (unsigned reg, unsigned val):
unsigned value = (reg << 8) | (val & 0xff)
gpio_clear (SP_PORT, 1 << SPEN) gpio_clear (SP_PORT, 1 << SPEN)
udelay (1) udelay (1)
unsigned value = (reg << 8) | (val & 0xff)
for unsigned i = 0; i < 16; ++i, value <<= 1: for unsigned i = 0; i < 16; ++i, value <<= 1:
gpio_clear (SP_PORT, 1 << SPCK) gpio_clear (SP_PORT, 1 << SPCK)
if value & 0x8000: if value & 0x8000:
@ -97,7 +97,7 @@ static void write_reg (unsigned reg, unsigned val):
gpio_clear (SP_PORT, 1 << SPDA) gpio_clear (SP_PORT, 1 << SPDA)
udelay (4) udelay (4)
gpio_set (SP_PORT, 1 << SPCK) gpio_set (SP_PORT, 1 << SPCK)
udelay (1) udelay (4)
gpio_set (SP_PORT, 1 << SPEN) gpio_set (SP_PORT, 1 << SPEN)
udelay(4) udelay(4)
#endif #endif
@ -111,7 +111,7 @@ static void reset ():
unsigned hsync = 80, hpre = 80, hpost = 0 unsigned hsync = 80, hpre = 80, hpost = 0
// One clock pulse per pixel. // One clock pulse per pixel.
unsigned extra = 0 unsigned cpp = 1
// Bits per pixel. // Bits per pixel.
unsigned bpp = LCD_CTRL_BPP_16 unsigned bpp = LCD_CTRL_BPP_16
// Configuration. // Configuration.
@ -120,39 +120,30 @@ static void reset ():
unsigned cfg = MODE_TFT_GEN | VSYNC_N unsigned cfg = MODE_TFT_GEN | VSYNC_N
#elif defined (NANONOTE) #elif defined (NANONOTE)
// Note that the sync pulse is part of the pre-display region. // Note that the sync pulse is part of the pre-display region.
// Horizontal timings.
unsigned hsync = 1, hpre = 141, hpost = 273
// Vertical timings. // Vertical timings.
unsigned vsync = 1, vpre = 21, vpost = 2 unsigned vsync = 1, vpre = 21, vpost = 2
// Horizontal timings. // 3 clocks per pixel.
unsigned hsync = 1, hpre = 70, hpost = 686 unsigned cpp = 3
// 3 bytes per pixel, so for the display area 2 extra clocks are sent.
unsigned extra = 2
// Bits per pixel. // Bits per pixel.
unsigned bpp = LCD_CTRL_BPP_18_24 unsigned bpp = LCD_CTRL_BPP_18_24
// Configuration. // Configuration.
unsigned cfg = LCD_CFG_MODE_SERIAL_TFT | LCD_CFG_HSP | LCD_CFG_VSP unsigned cfg = LCD_CFG_MODE_SERIAL_TFT | LCD_CFG_HSP | LCD_CFG_VSP
// Set up SPI pins. // 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)) gpio_set (SP_PORT, (1 << SPEN) | (1 << SPCK))
#else #else
#error unknown board #error unknown board
#endif #endif
// Note that the sync pulse is part of the pre-display region. // 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 vpe = vsync, vds = vpre, vde = vds + v, vt = vde + vpost
unsigned hps = 0, hpe = hps + hsync, hds = hps + hpre, hde = hds + h, ht = hde + hpost unsigned hpe = hsync, hds = hpre, hde = hds + cpp * 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
cpm_stop_lcd () cpm_stop_lcd ()
unsigned pixclock = fps * (ht + extra * h) * vt unsigned pixclock = fps * ht * vt
#if defined (TRENDTAC) #if defined (TRENDTAC)
unsigned pllout = cpm_get_pllout () unsigned pllout = cpm_get_pllout ()
@ -165,30 +156,47 @@ static void reset ():
CPM_CFCR |= CPM_CFCR_UPE CPM_CFCR |= CPM_CFCR_UPE
#elif defined (NANONOTE) #elif defined (NANONOTE)
unsigned val = cpm_get_pllout2 () / pixclock - 1 unsigned val = cpm_get_pllout2 () / pixclock - 1
kdebug ("clock: ")
kdebug_num (val) kdebug_num (val)
kdebug ("\n") kdebug ("\n")
assert (val < 0x400) //assert (val < 0x400)
cpm_set_pixdiv (val); //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) assert (val < 0x20)
cpm_set_ldiv (val) //cpm_set_ldiv (val)
// Update dividers. // Update dividers.
CPM_CPCCR |= CPM_CPCCR_CE //CPM_CPCCR |= CPM_CPCCR_CE
#else
#error "Unknown board"
#endif #endif
cpm_start_lcd () cpm_start_lcd ()
LCD_DA0 = physical_descriptor
lcd_set_ena ()
//lcd_enable_eof_intr ()
#ifdef NANONOTE #ifdef NANONOTE
// Reset registers. // Reset the controller.
write_reg (BACKLIGHT1, 0) //write_reg (BACKLIGHT1, 0x1e)
// Enable display. // Enable display.
write_reg (BACKLIGHT1, 0x5f) write_reg (BACKLIGHT1, 0x5f)
// Set data to rgbrgbrgb input, with a delta color filter.
write_reg (COLOR, 0x01)
#endif #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): static void putchar (unsigned x, unsigned y, unsigned ch, unsigned fg = 0xffff, unsigned bg = 0x0000):
if ch < 32 || ch > 126: if ch < 32 || ch > 126:
ch = 127 ch = 127
@ -239,7 +247,9 @@ static void log_msg ():
log_char ('\n') log_char ('\n')
enum captype: enum captype:
#ifdef TRENDTAC
LOG LOG
#endif
SET_EOF_CB SET_EOF_CB
Kernel::Num start (): Kernel::Num start ():
@ -266,6 +276,7 @@ Kernel::Num start ():
#if defined (TRENDTAC) #if defined (TRENDTAC)
LCD_FRAMEBUFFER_BASE[y * h + x] = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3) LCD_FRAMEBUFFER_BASE[y * h + x] = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3)
#elif defined (NANONOTE) #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 + 2] = r
LCD_FRAMEBUFFER_BASE[(y * h + x) * Bpp + 1] = g LCD_FRAMEBUFFER_BASE[(y * h + x) * Bpp + 1] = g
LCD_FRAMEBUFFER_BASE[(y * h + x) * Bpp + 0] = b 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") __asm__ volatile ("lw $a0, %0\ncache 0x15, 0($a0)" :: "m"(dptr) : "memory", "a0")
reset () reset ()
Kernel::Cap logcap = Kernel::my_receiver.create_capability (LOG)
#if defined (TRENDTAC) #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") __asm__ volatile ("li $a0, 1\nlw $a1, %0\nbreak" :: "m"(logcap.code): "a0", "a1", "memory")
#endif #endif
@ -310,9 +321,11 @@ Kernel::Num start ():
reply.invoke () reply.invoke ()
Kernel::free_cap (reply) Kernel::free_cap (reply)
break break
#ifdef TRENDTAC
case LOG: case LOG:
log_char (Kernel::recv.data[0].l) log_char (Kernel::recv.data[0].l)
break break
#endif
default: default:
log_char ('~') log_char ('~')
break break

View File

@ -16,6 +16,7 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "iris.hh"
#include "devices.hh" #include "devices.hh"
#define ARCH #define ARCH
#include "arch.hh" #include "arch.hh"
@ -153,6 +154,7 @@ void Udc::init ():
configuration = 0 configuration = 0
size = 0 size = 0
// exit suspend mode by reading the interrupt register. // exit suspend mode by reading the interrupt register.
cpm_start_udc ()
unsigned i = UDC_INTRUSB unsigned i = UDC_INTRUSB
// reset all pending endpoint interrupts. // reset all pending endpoint interrupts.
i = UDC_INTRIN i = UDC_INTRIN
@ -331,6 +333,7 @@ enum pdata:
Kernel::Num start (): Kernel::Num start ():
map_udc () map_udc ()
map_gpio () map_gpio ()
map_cpm ()
Udc udc Udc udc
udc.init () udc.init ()

View File

@ -89,13 +89,13 @@ struct Device : public Kernel::Cap:
Kernel::Cap create_user (Kernel::Memory storage): Kernel::Cap create_user (Kernel::Memory storage):
iocall (storage, CAP_MASTER_DIRECT | CREATE_USER) iocall (storage, CAP_MASTER_DIRECT | CREATE_USER)
return Kernel::get_arg () 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): void destroy_user (Kernel::Cap user):
ocall (user, CAP_MASTER_DIRECT | DESTROY_USER) ocall (user, CAP_MASTER_DIRECT | DESTROY_USER)
// Make user inactive. // Make user inactive.
void unuse (Kernel::Cap user): void unuse (Kernel::Cap user):
ocall (user, CAP_MASTER_DIRECT | UNUSE) ocall (user, CAP_MASTER_DIRECT | UNUSE)
// Make user active. // Make user active. It makes the previous active user inactive.
void use (Kernel::Cap user): void use (Kernel::Cap user):
ocall (user, CAP_MASTER_DIRECT | USE) 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. // Set the event callback. Currently pressed keys emit a key press event to the new callback immediately.
void set_cb (Kernel::Cap cb): void set_cb (Kernel::Cap cb):
ocall (cb, CAP_MASTER_DIRECT | SET_CB) ocall (cb, CAP_MASTER_DIRECT | SET_CB)
// Get the number of keys on the keyboard.
unsigned get_num_keys (): unsigned get_num_keys ():
return call (CAP_MASTER_DIRECT | GET_NUM_KEYS).l 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): void get_keys (unsigned first):
call (CAP_MASTER_DIRECT | GET_KEYS, first) call (CAP_MASTER_DIRECT | GET_KEYS, first)
@ -154,7 +156,7 @@ struct Buzzer : public Kernel::Cap:
BEEP = Keyboard::ID BEEP = Keyboard::ID
STOP STOP
ID 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 ()): 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)) ocall (cb, Kernel::Num (CAP_MASTER_DIRECT | BEEP, volume), Kernel::Num (freq, ms))
// Abort current beep, if any. // Abort current beep, if any.
@ -192,8 +194,9 @@ struct Display : public Kernel::Cap:
// File system interface. // File system interface.
// filesystem-related interfaces: directory, stream, seekable, mappable. // filesystem-related interfaces: directory, stream, seekable.
// Normal files implement at least stream or seekable file. Directories implement directory. // Normal files implement stream and/or seekable. Directories implement directory.
// Seekable is not a class, it is identical to [W]String.
// Directory interface. // Directory interface.
struct Directory : public Kernel::Cap: struct Directory : public Kernel::Cap:
@ -201,12 +204,8 @@ struct Directory : public Kernel::Cap:
enum request: enum request:
GET_SIZE = Display::ID GET_SIZE = Display::ID
GET_NAME GET_NAME
GET_FILE GET_FILE_RO
GET_FILE_INFO GET_FILE_INFO
CREATE_FILE
DELETE_FILE
LOCK
UNLOCK
LOCK_RO LOCK_RO
UNLOCK_RO UNLOCK_RO
ID ID
@ -218,12 +217,31 @@ struct Directory : public Kernel::Cap:
icall (CAP_MASTER_DIRECT | GET_NAME, idx) icall (CAP_MASTER_DIRECT | GET_NAME, idx)
return Kernel::get_arg () return Kernel::get_arg ()
// Get the file. // 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): Kernel::Cap get_file (Kernel::Num idx):
icall (CAP_MASTER_DIRECT | GET_FILE, idx) icall (CAP_MASTER_DIRECT | GET_FILE, idx)
return Kernel::get_arg () 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. // Create a new file. After this, any index may map to a different file.
Kernel::Cap create_file (String name): Kernel::Cap create_file (String name):
icall (CAP_MASTER_DIRECT | CREATE_FILE) 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. // Unlock the directory. Write operations can only be done when the directory is locked.
void unlock (): void unlock ():
call (CAP_MASTER_DIRECT | LOCK) 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. // Stream interface.
struct Stream : public Kernel::Cap: struct Stream : public Kernel::Cap:
Stream (Kernel::Cap c = Kernel::Cap ()) : Kernel::Cap (c): Stream (Kernel::Cap c = Kernel::Cap ()) : Kernel::Cap (c):
enum request: enum request:
READ = Directory::ID READ = WDirectory::ID
WRITE WRITE
ID ID
// Try to read size bytes. Returns the number of bytes successfully read. // Try to read size bytes. Returns the number of bytes successfully read.
Kernel::Num read (Kernel::Num size): Kernel::Num read (Kernel::Num size, bool block):
return icall (CAP_MASTER_DIRECT | READ, size) return icall (Kernel::Num (CAP_MASTER_DIRECT | READ, block), size)
// Try to write size bytes. Returns the number of bytes successfully written. // Try to write size bytes. Returns the number of bytes successfully written.
Kernel::Num write (String s, Kernel::Num size): Kernel::Num write (String s, Kernel::Num size):
return ocall (s, CAP_MASTER_DIRECT | WRITE, 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. // Block device interface.
struct Block_device : public Mappable: struct Block_device : public WString:
Block_device (Kernel::Cap c = Kernel::Cap ()) : Mappable (c): Block_device (Kernel::Cap c = Kernel::Cap ()) : WString (c):
// TODO: to be designed. // TODO: to be designed.
@ -295,6 +284,5 @@ struct Block_device : public Mappable:
// Pointer interface. (Only movement; buttons follow keyboard interface.) // Pointer interface. (Only movement; buttons follow keyboard interface.)
// Network interface. // Network interface.
// Camera interface. // Camera interface.
// Terminal interfaces.
#endif #endif

View File

@ -487,7 +487,7 @@ namespace Kernel:
my_thread.call (CAP_MASTER_DIRECT | Thread::DBG_SEND, Num (code, bits)) my_thread.call (CAP_MASTER_DIRECT | Thread::DBG_SEND, Num (code, bits))
inline void reboot (): inline void reboot ():
my_thread.call (CAP_MASTER_DIRECT | Thread::PRIV_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) my_thread.call (CAP_MASTER_DIRECT | Thread::PRIV_PANIC, code)
void Receiver::sleep (unsigned value): void Receiver::sleep (unsigned value):

View File

@ -21,7 +21,6 @@
// Include definitions which are shared with user space. // Include definitions which are shared with user space.
#define __KERNEL__ #define __KERNEL__
#include "iris.hh"
// Normally define all variables in this file as extern. // Normally define all variables in this file as extern.
// Exactly once (in data.ccp), EXTERN is predefined empty. // Exactly once (in data.ccp), EXTERN is predefined empty.
@ -38,6 +37,20 @@ struct kCapability
struct kCaps struct kCaps
struct kMemory 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 kPage *kPageP
typedef kThread *kThreadP typedef kThread *kThreadP
typedef kMessage *kMessageP typedef kMessage *kMessageP
@ -217,9 +230,6 @@ extern "C":
#ifndef NDEBUG #ifndef NDEBUG
EXTERN Kernel::Num dbg_code EXTERN Kernel::Num dbg_code
EXTERN kCapRef dbg_cap 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 dbg_send (unsigned num, unsigned bits)
void check (unsigned num, char const *msg) void check (unsigned num, char const *msg)
#define dbg_check() ::check (__LINE__, __FILE__) #define dbg_check() ::check (__LINE__, __FILE__)
@ -229,9 +239,6 @@ extern "C":
#define dpanic(n, msg) panic (n, msg) #define dpanic(n, msg) panic (n, msg)
#define dbg_print() top_memory.print (__LINE__, 0) #define dbg_print() top_memory.print (__LINE__, 0)
#else #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 dbg_send(n, m) do {} while (0)
#define check (n, x) do {} while (0) #define check (n, x) do {} while (0)
#define dpanic(n, x) do {} while (0) #define dpanic(n, x) do {} while (0)

View File

@ -6,6 +6,8 @@ extern unsigned _end
static void clear_page (unsigned page, unsigned num = 1): static void clear_page (unsigned page, unsigned num = 1):
for unsigned i = 0; i < (num << (PAGE_BITS - 2)); ++i: for unsigned i = 0; i < (num << (PAGE_BITS - 2)); ++i:
((unsigned *)page)[i] = 0 ((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 #if 0
@ -48,7 +50,7 @@ unsigned init_memory (unsigned mem):
first_free = (kFreePages *)(((unsigned)&_end + ~PAGE_MASK) & PAGE_MASK) first_free = (kFreePages *)(((unsigned)&_end + ~PAGE_MASK) & PAGE_MASK)
first_free->prev = NULL first_free->prev = NULL
first_free->next = 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 return first_free->num
unsigned phys_alloc (unsigned num): unsigned phys_alloc (unsigned num):

View File

@ -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: mips/nanonote/sdram-setup.ld
mips/nanonote/sdram-setup.elf: LDFLAGS = --omagic -T 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/boot.o: TARGET_FLAGS = -DMEMORY_SIZE="32 << 20"
mips/entry.o: $(addsuffix .elf,$(boot_threads))
mips/init.o: TARGET_FLAGS = -I/usr/include mips/init.o: TARGET_FLAGS = -I/usr/include
$(addsuffix .elf,$(boot_threads)): TARGET_FLAGS = -I. $(addsuffix .elf,$(boot_threads)): TARGET_FLAGS = -I.
$(addsuffix .elf,$(boot_threads)): LDFLAGS = -EL $(addsuffix .elf,$(boot_threads)): LDFLAGS = -EL
$(addprefix boot-programs/,$(addsuffix .cc,$(boot_threads))): devices.hh keys.hh $(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 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 $@ $(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 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

View File

@ -21,14 +21,21 @@
#include "kernel.hh" #include "kernel.hh"
void board_init (): void board_init ():
unsigned cpm_uhccdr = CPM_UHCCDR
unsigned cpm_cpccr = CPM_CPCCR
unsigned cpm_cppcr = CPM_CPPCR
pll_init () pll_init ()
cpm_start_all () cpm_stop_all ()
cpm_start_uart0 ()
cpm_start_tcu ()
cpm_start_lcd ()
gpio_as_uart0 () gpio_as_uart0 ()
gpio_as_sdram_16bit () gpio_as_sdram_16bit ()
gpio_as_nand () gpio_as_nand ()
gpio_as_aic () gpio_as_aic ()
gpio_as_msc () gpio_as_msc ()
gpio_as_lcd_16bit () gpio_as_lcd_16bit ()
gpio_as_pwm4 ()
// Set up memory. // Set up memory.
setup_sdram () setup_sdram ()
// Use some gpio pins for lcd. // Use some gpio pins for lcd.
@ -38,6 +45,7 @@ void board_init ():
gpio_as_output (3, 1 << 27) gpio_as_output (3, 1 << 27)
// Set up keyboard: this breaks uart receive. // Set up keyboard: this breaks uart receive.
gpio_as_gpio (3, 0x05fc0000) gpio_as_gpio (3, 0x05fc0000)
// Set up timed interrupts.
tcu_stop_counter (0) tcu_stop_counter (0)
tcu_select_extalclk (0) tcu_select_extalclk (0)
tcu_select_clk_div4 (0) tcu_select_clk_div4 (0)
@ -62,6 +70,10 @@ void board_init ():
UART0_FCR = UARTFCR_UUE | UARTFCR_FE | UARTFCR_RFLS | UARTFCR_TFLS UART0_FCR = UARTFCR_UUE | UARTFCR_FE | UARTFCR_RFLS | UARTFCR_TFLS
dbg_code.l = 1 dbg_code.l = 1
dbg_log ("Serial port initialized\n") dbg_log ("Serial port initialized\n")
dbg_log_num (CPM_CPCCR)
dbg_log ("+")
dbg_log_num (CPM_CPPCR)
dbg_log ("\n")
void arch_reboot (): void arch_reboot ():
// Wait for serial port to be done. // Wait for serial port to be done.

View File

@ -2346,18 +2346,16 @@ static void gpio_disable_pull (unsigned p, unsigned pins):
// CPM // CPM
//************************************************************************** //**************************************************************************
static void pll_init (): static void pll_init ():
// The cpu clock is set to 252 MHz // The cpu clock frequency
unsigned const cpu_clock = 252000000 //unsigned const cpu_clock = 336000000
// The usb clock must be 48 MHz unsigned const cpu_clock = 210000000
unsigned const usb_clock = 48000000 unsigned const pixclock = 27000000
// ssi clock must be 12 MHz, therefore it is taken directly from JZ_EXTAL, not from divided pll output. // Configure the pll frequency to cpu_clock.
// 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.
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 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 (): static unsigned cpm_get_pllm ():
return (CPM_CPPCR & CPM_CPPCR_PLLM_MASK) >> CPM_CPPCR_PLLM_BIT 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 ) #define rtc_set_scratch_pattern(n) (RTC_HSPR = n )
#ifdef __KERNEL__
static void setup_sdram (): static void setup_sdram ():
// SDRAM BANK Number: 1, 2 // SDRAM BANK Number: 1, 2
unsigned CONFIG_NR_DRAM_BANKS = 1 unsigned CONFIG_NR_DRAM_BANKS = 1
@ -3682,6 +3680,31 @@ static void setup_sdram ():
// Set back to basic DMCR value // Set back to basic DMCR value
EMC_DMCR = dmcr | EMC_DMCR_RFSH | EMC_DMCR_MRSET 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 #endif

View File

@ -135,7 +135,7 @@ nanonote::nanonote (unsigned skip):
// Get info will reset the device if it has already booted into Iris. // Get info will reset the device if it has already booted into Iris.
get_cpu_info () get_cpu_info ()
usb_close (handle) usb_close (handle)
sleep (1) sleep (5)
if !find_device (skip): if !find_device (skip):
std::cerr << "unable to find NanoNote device again.\n"; std::cerr << "unable to find NanoNote device again.\n";
throw "unable to find NanoNote device again"; throw "unable to find NanoNote device again";

View File

@ -18,6 +18,9 @@
// This runs like the kernel. In particular, it doesn't want userspace declarations. // This runs like the kernel. In particular, it doesn't want userspace declarations.
#define __KERNEL__ #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" #include "jz4740.hh"
asm volatile (".set noreorder\n" asm volatile (".set noreorder\n"

View File

@ -25,7 +25,7 @@ thread0:
.balign 0x1000 .balign 0x1000
thread1: thread1:
.incbin "udc.elf" .incbin "lcd.elf"
.balign 0x1000 .balign 0x1000
thread2: thread2:
@ -41,7 +41,7 @@ thread4:
.balign 0x1000 .balign 0x1000
thread5: thread5:
.incbin "lcd.elf" .incbin "udc.elf"
thread6: thread6: