mirror of
git://projects.qi-hardware.com/iris.git
synced 2024-12-29 03:21:09 +02:00
Looking for the lcd problem and more
This commit is contained in:
parent
a383b3ffd3
commit
cf496f031f
1
Makefile
1
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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -16,6 +16,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#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 ()
|
||||
|
84
devices.hhp
84
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
|
||||
|
2
iris.hhp
2
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):
|
||||
|
21
kernel.hhp
21
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)
|
||||
|
@ -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):
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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";
|
||||
|
@ -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"
|
||||
|
@ -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:
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user