mirror of
git://projects.qi-hardware.com/iris.git
synced 2024-11-04 23:19:41 +02:00
lots of stuff
This commit is contained in:
parent
afb496f20b
commit
a383b3ffd3
3
.gitignore
vendored
3
.gitignore
vendored
@ -10,6 +10,9 @@ gpio
|
|||||||
lcd
|
lcd
|
||||||
init
|
init
|
||||||
udc
|
udc
|
||||||
|
buzzer
|
||||||
|
metronome
|
||||||
|
nanonote-gpio
|
||||||
boot-programs/charset.data
|
boot-programs/charset.data
|
||||||
mips/nanonote/sdram-setup.raw
|
mips/nanonote/sdram-setup.raw
|
||||||
nanonote-boot
|
nanonote-boot
|
||||||
|
2
Makefile
2
Makefile
@ -42,7 +42,7 @@ PYPP = /usr/bin/pypp
|
|||||||
%.o:%.cc Makefile Makefile.arch $(headers)
|
%.o:%.cc Makefile Makefile.arch $(headers)
|
||||||
$(CC) $(CPPFLAGS) $(TARGET_FLAGS) $(CXXFLAGS) -c $< -o $@
|
$(CC) $(CPPFLAGS) $(TARGET_FLAGS) $(CXXFLAGS) -c $< -o $@
|
||||||
|
|
||||||
%: boot-programs/crt0.o boot-programs/%.o
|
%.elf: boot-programs/crt0.o boot-programs/%.o
|
||||||
$(LD) $(LDFLAGS) $(filter %.o,$^) -o $@
|
$(LD) $(LDFLAGS) $(filter %.o,$^) -o $@
|
||||||
#$(OBJCOPY) -S $(OBJCOPYFLAGS) $@
|
#$(OBJCOPY) -S $(OBJCOPYFLAGS) $@
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ Kernel::Num start ():
|
|||||||
DevBuzzer buzzer
|
DevBuzzer buzzer
|
||||||
|
|
||||||
Device dev = Kernel::my_receiver.create_capability (BUZZER)
|
Device dev = Kernel::my_receiver.create_capability (BUZZER)
|
||||||
Kernel::my_parent.ocall (dev.copy (), Buzzer::ID)
|
Kernel::my_parent.provide_device <Buzzer> (dev.copy ())
|
||||||
Kernel::free_cap (dev)
|
Kernel::free_cap (dev)
|
||||||
unsigned user (~0)
|
unsigned user (~0)
|
||||||
unsigned next_user (0)
|
unsigned next_user (0)
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
// 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 "devices.hh"
|
#include "devices.hh"
|
||||||
#include "init.hh"
|
|
||||||
#define ARCH
|
#define ARCH
|
||||||
#include "arch.hh"
|
#include "arch.hh"
|
||||||
|
|
||||||
@ -247,6 +246,12 @@ class Pwm:
|
|||||||
GPIO_GPDR (GPIO_PWM_ENABLE_PORT) &= ~(1 << GPIO_PWM_ENABLE)
|
GPIO_GPDR (GPIO_PWM_ENABLE_PORT) &= ~(1 << GPIO_PWM_ENABLE)
|
||||||
// TODO: make it really work as a pwm instead of a switch; check if pwm1 is connected to anything.
|
// TODO: make it really work as a pwm instead of a switch; check if pwm1 is connected to anything.
|
||||||
|
|
||||||
|
enum codes:
|
||||||
|
KEYBOARD = 32
|
||||||
|
TOUCHPAD
|
||||||
|
LOCKLEDS
|
||||||
|
PWM
|
||||||
|
|
||||||
Kernel::Num start ():
|
Kernel::Num start ():
|
||||||
Kernel::schedule ()
|
Kernel::schedule ()
|
||||||
map_gpio ()
|
map_gpio ()
|
||||||
@ -260,7 +265,12 @@ Kernel::Num start ():
|
|||||||
Lockleds leds
|
Lockleds leds
|
||||||
Pwm pwm
|
Pwm pwm
|
||||||
|
|
||||||
((Init)Kernel::my_parent).register_gpio ()
|
Kernel::Cap c = Kernel::my_receiver.create_capability (KEYBOARD)
|
||||||
|
Kernel::my_parent.provide_device <Keyboard> (c.copy (), 0)
|
||||||
|
Kernel::free_cap (c)
|
||||||
|
c = Kernel::my_receiver.create_capability (TOUCHPAD)
|
||||||
|
Kernel::my_parent.provide_device <Keyboard> (c.copy (), 1)
|
||||||
|
Kernel::free_cap (c)
|
||||||
|
|
||||||
if kbd.is_scanning ():
|
if kbd.is_scanning ():
|
||||||
Kernel::my_receiver.set_alarm (ALARM_INTERVAL)
|
Kernel::my_receiver.set_alarm (ALARM_INTERVAL)
|
||||||
@ -286,23 +296,23 @@ Kernel::Num start ():
|
|||||||
// Reregister the interrupt.
|
// Reregister the interrupt.
|
||||||
Kernel::register_interrupt (IRQ_GPIO0)
|
Kernel::register_interrupt (IRQ_GPIO0)
|
||||||
break
|
break
|
||||||
case Init::GPIO_KEYBOARD:
|
case KEYBOARD:
|
||||||
set_cb (KEYBOARD_EVENT)
|
set_cb (KEYBOARD_EVENT)
|
||||||
Kernel::recv.reply.invoke ()
|
Kernel::recv.reply.invoke ()
|
||||||
kbd.send_initial ()
|
kbd.send_initial ()
|
||||||
event (KEYBOARD_EVENT, ~0)
|
event (KEYBOARD_EVENT, ~0)
|
||||||
break
|
break
|
||||||
case Init::GPIO_TOUCHPAD:
|
case TOUCHPAD:
|
||||||
set_cb (TOUCHPAD_EVENT)
|
set_cb (TOUCHPAD_EVENT)
|
||||||
Kernel::recv.reply.invoke ()
|
Kernel::recv.reply.invoke ()
|
||||||
tp.send_initial ()
|
tp.send_initial ()
|
||||||
event (TOUCHPAD_EVENT, ~0)
|
event (TOUCHPAD_EVENT, ~0)
|
||||||
break
|
break
|
||||||
case Init::GPIO_LOCKLEDS:
|
case LOCKLEDS:
|
||||||
leds.set (Kernel::recv.data[0].l)
|
leds.set (Kernel::recv.data[0].l)
|
||||||
Kernel::recv.reply.invoke ()
|
Kernel::recv.reply.invoke ()
|
||||||
break
|
break
|
||||||
case Init::GPIO_PWM:
|
case PWM:
|
||||||
pwm.set_backlight (Kernel::recv.data[0].l)
|
pwm.set_backlight (Kernel::recv.data[0].l)
|
||||||
Kernel::recv.reply.invoke ()
|
Kernel::recv.reply.invoke ()
|
||||||
break
|
break
|
||||||
|
@ -60,7 +60,6 @@ static void setup ():
|
|||||||
unsigned state = 0
|
unsigned state = 0
|
||||||
Kernel::Caps caps = Kernel::my_memory.create_caps (32)
|
Kernel::Caps caps = Kernel::my_memory.create_caps (32)
|
||||||
slot = caps.use ()
|
slot = caps.use ()
|
||||||
Kernel::Caps slot0 = Kernel::my_thread.get_caps (0)
|
|
||||||
Kernel::Cap user
|
Kernel::Cap user
|
||||||
unsigned device
|
unsigned device
|
||||||
while true:
|
while true:
|
||||||
@ -68,32 +67,37 @@ static void setup ():
|
|||||||
Kernel::Cap reply = Kernel::get_reply ()
|
Kernel::Cap reply = Kernel::get_reply ()
|
||||||
Kernel::Cap arg = Kernel::get_arg ()
|
Kernel::Cap arg = Kernel::get_arg ()
|
||||||
switch Kernel::recv.data[0].l:
|
switch Kernel::recv.data[0].l:
|
||||||
case Keyboard::ID:
|
case Parent::PROVIDE_DEVICE:
|
||||||
switch Kernel::recv.data[0].h:
|
switch Kernel::recv.data[1].l:
|
||||||
case 0:
|
case Keyboard::ID:
|
||||||
caps.set (KBDDEV, arg.copy ())
|
switch Kernel::recv.data[0].h:
|
||||||
kbd_dev = Kernel::Cap (slot, KBDDEV)
|
case 0:
|
||||||
|
caps.set (KBDDEV, arg.copy ())
|
||||||
|
kbd_dev = Kernel::Cap (slot, KBDDEV)
|
||||||
|
break
|
||||||
|
case 1:
|
||||||
|
caps.set (SYSREQ, arg.copy ())
|
||||||
|
sysreq = Kernel::Cap (slot, SYSREQ)
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
kdebug ("unexpected keyboard\n")
|
||||||
|
break
|
||||||
|
reply.invoke ()
|
||||||
|
Kernel::free_cap (reply)
|
||||||
break
|
break
|
||||||
case 1:
|
case Buzzer::ID:
|
||||||
caps.set (SYSREQ, arg.copy ())
|
caps.set (BUZDEV, arg.copy ())
|
||||||
sysreq = Kernel::Cap (slot, SYSREQ)
|
buz_dev = Kernel::Cap (slot, BUZDEV)
|
||||||
|
reply.invoke ()
|
||||||
|
Kernel::free_cap (reply)
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
kdebug ("unexpected keyboard\n")
|
kdebug ("unexpected device\n")
|
||||||
break
|
break
|
||||||
reply.invoke ()
|
|
||||||
Kernel::free_cap (reply)
|
|
||||||
break
|
|
||||||
case Buzzer::ID:
|
|
||||||
caps.set (BUZDEV, arg.copy ())
|
|
||||||
buz_dev = Kernel::Cap (slot, BUZDEV)
|
|
||||||
reply.invoke ()
|
|
||||||
Kernel::free_cap (reply)
|
|
||||||
break
|
break
|
||||||
case Parent::GET_DEVICE:
|
case Parent::GET_DEVICE:
|
||||||
user = reply
|
user = reply
|
||||||
device = Kernel::recv.data[1].l
|
device = Kernel::recv.data[1].l
|
||||||
slot0.print (reply.idx ())
|
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
kdebug ("unknown setup request for init\n")
|
kdebug ("unknown setup request for init\n")
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
// 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 "devices.hh"
|
#include "devices.hh"
|
||||||
#include "init.hh"
|
|
||||||
#define ARCH
|
#define ARCH
|
||||||
#include "arch.hh"
|
#include "arch.hh"
|
||||||
|
|
||||||
@ -28,11 +27,9 @@ extern unsigned char const charset[127-32][6]
|
|||||||
#define assert(x) do { while (!(x)) kdebug ("assertion failed " #x); } while (0)
|
#define assert(x) do { while (!(x)) kdebug ("assertion failed " #x); } while (0)
|
||||||
|
|
||||||
#if defined (TRENDTAC)
|
#if defined (TRENDTAC)
|
||||||
// For now, support only 16 bpp.
|
static unsigned h = 800, v = 480, fps = 60, Bpp = 2
|
||||||
// Screen is 800x480 tft.
|
#elif defined (NANONOTE)
|
||||||
static unsigned h = 800, v = 480, hs = 80, vs = 20, fps = 60, Bpp = 2
|
static unsigned h = 320, v = 240, fps = 70, Bpp = 4
|
||||||
#else if defined (NANONOTE)
|
|
||||||
static unsigned h = 320, v = 240, fps = 70, Bpp = 3
|
|
||||||
#else
|
#else
|
||||||
#error unknown board
|
#error unknown board
|
||||||
#endif
|
#endif
|
||||||
@ -40,19 +37,80 @@ static unsigned h = 320, v = 240, fps = 70, Bpp = 3
|
|||||||
|
|
||||||
static unsigned physical_descriptor
|
static unsigned physical_descriptor
|
||||||
|
|
||||||
struct Descriptor:
|
/**/struct Descriptor {
|
||||||
unsigned next
|
unsigned next;
|
||||||
unsigned frame
|
unsigned frame;
|
||||||
unsigned id
|
unsigned id;
|
||||||
unsigned cmd
|
unsigned cmd;
|
||||||
|
} __attribute__ ((packed))
|
||||||
|
|
||||||
|
#if defined (NANONOTE)
|
||||||
|
#define SP_PORT 2
|
||||||
|
#define SPEN 21
|
||||||
|
#define SPDA 22
|
||||||
|
#define SPCK 23
|
||||||
|
|
||||||
|
static void udelay (unsigned num):
|
||||||
|
for unsigned i = 0; i < num * (JZ_EXTAL / 1000000); ++i:
|
||||||
|
// set 0 does nothing, but costs at least one clock pulse.
|
||||||
|
gpio_set (SP_PORT, 0)
|
||||||
|
|
||||||
|
// Register names. The registers are not named in the datasheet, and in some cases the name only describes a part of the bits in it.
|
||||||
|
// The registers with bit 6 set have bit 7 set instead, because of the transfer method.
|
||||||
|
enum spi_reg:
|
||||||
|
AC = 0x00
|
||||||
|
DC = 0x01
|
||||||
|
BRIGHTNESS = 0x03
|
||||||
|
FORMAT = 0x04
|
||||||
|
BACKLIGHT1 = 0x05
|
||||||
|
VBLANK = 0x06
|
||||||
|
HBLANK = 0x07
|
||||||
|
BACKLIGHT2 = 0x08
|
||||||
|
SYNC = 0x0b
|
||||||
|
POLARITY = 0x0c
|
||||||
|
CONTRAST_B = 0x0d
|
||||||
|
SUB_CONTRAST_R = 0x0e
|
||||||
|
SUB_BRIGHTNESS_R= 0x0f
|
||||||
|
SUB_CONTRAST_B = 0x10
|
||||||
|
SUB_BRIGHTNESS_B= 0x11
|
||||||
|
TRIM = 0x12
|
||||||
|
COLOR = 0x13
|
||||||
|
GAMMA = 0x16
|
||||||
|
GAMMA1 = 0x17
|
||||||
|
GAMMA2 = 0x18
|
||||||
|
GAMMA3 = 0x19
|
||||||
|
GAMMA4 = 0x1a
|
||||||
|
INVERSION = 0xa5
|
||||||
|
HLEVEL = 0xa6
|
||||||
|
LLEVEL = 0xa7
|
||||||
|
FB = 0xb1
|
||||||
|
|
||||||
|
static void write_reg (unsigned reg, unsigned val):
|
||||||
|
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:
|
||||||
|
gpio_set (SP_PORT, 1 << SPDA)
|
||||||
|
else:
|
||||||
|
gpio_clear (SP_PORT, 1 << SPDA)
|
||||||
|
udelay (4)
|
||||||
|
gpio_set (SP_PORT, 1 << SPCK)
|
||||||
|
udelay (1)
|
||||||
|
gpio_set (SP_PORT, 1 << SPEN)
|
||||||
|
udelay(4)
|
||||||
|
#endif
|
||||||
|
|
||||||
static void reset ():
|
static void reset ():
|
||||||
#if defined (TRENDTAC)
|
#if defined (TRENDTAC)
|
||||||
unsigned fps = 60
|
// Note that the sync pulse is part of the pre-display region.
|
||||||
// Vertical timings.
|
// Vertical timings.
|
||||||
unsigned vps = 0, vpe = vps + 20, vds = vpe, vde = vds + v, vt = vde
|
unsigned vsync = 20, vpre = 20, vpost = 0
|
||||||
// Horizontal timings.
|
// Horizontal timings.
|
||||||
unsigned hps = 0, hpe = hps + 80, hds = hpe, hde = hds + h, ht = hde
|
unsigned hsync = 80, hpre = 80, hpost = 0
|
||||||
|
|
||||||
|
// One clock pulse per pixel.
|
||||||
unsigned extra = 0
|
unsigned extra = 0
|
||||||
// Bits per pixel.
|
// Bits per pixel.
|
||||||
unsigned bpp = LCD_CTRL_BPP_16
|
unsigned bpp = LCD_CTRL_BPP_16
|
||||||
@ -60,33 +118,41 @@ static void reset ():
|
|||||||
#define MODE_TFT_GEN 0
|
#define MODE_TFT_GEN 0
|
||||||
#define VSYNC_N (1 << 8)
|
#define VSYNC_N (1 << 8)
|
||||||
unsigned cfg = MODE_TFT_GEN | VSYNC_N
|
unsigned cfg = MODE_TFT_GEN | VSYNC_N
|
||||||
#elif defined (NANONOTE)
|
#elif defined (NANONOTE)
|
||||||
unsigned fps = 70
|
// Note that the sync pulse is part of the pre-display region.
|
||||||
// Vertical timings.
|
// Vertical timings.
|
||||||
unsigned vps = 0, vpe = vps + 1, vds = vpe + 20, vde = vds + v, vt = vde + 1
|
unsigned vsync = 1, vpre = 21, vpost = 2
|
||||||
// Horizontal timings.
|
// Horizontal timings.
|
||||||
unsigned hps = 0, hpe = hps + 1, hds = hpe + 140, hde = hds + h, ht = hde + 273
|
unsigned hsync = 1, hpre = 70, hpost = 686
|
||||||
|
|
||||||
// 3 bytes per pixel, so for the display area 2 extra clocks are sent.
|
// 3 bytes per pixel, so for the display area 2 extra clocks are sent.
|
||||||
unsigned extra = 2
|
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_TFT_SERIAL_TFT | LCD_CFG_PCP | LCD_CFG_HSP | LCD_CFG_VSP
|
unsigned cfg = LCD_CFG_MODE_SERIAL_TFT | LCD_CFG_HSP | LCD_CFG_VSP
|
||||||
#else
|
// Set up SPI pins.
|
||||||
#error unknown board
|
gpio_as_output(SP_PORT, (1 << SPEN) | (1 << SPCK) | (1 << SPDA))
|
||||||
#endif
|
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_CTRL = bpp | LCD_CTRL_BST_16
|
|
||||||
LCD_VSYNC = (vps << 16) | vpe
|
|
||||||
LCD_HSYNC = (hps << 16) | hpe
|
|
||||||
LCD_DAV = (vds << 16) | vde
|
|
||||||
LCD_DAH = (hds << 16) | hde
|
|
||||||
LCD_VAT = (ht << 16) | vt
|
|
||||||
LCD_CFG = cfg
|
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 * (hde - hds)) * vt
|
unsigned pixclock = fps * (ht + extra * h) * vt
|
||||||
|
|
||||||
#if defined (TRENDTAC)
|
#if defined (TRENDTAC)
|
||||||
unsigned pllout = cpm_get_pllout ()
|
unsigned pllout = cpm_get_pllout ()
|
||||||
@ -98,28 +164,30 @@ static void reset ():
|
|||||||
cpm_set_lcdclk_div (val)
|
cpm_set_lcdclk_div (val)
|
||||||
CPM_CFCR |= CPM_CFCR_UPE
|
CPM_CFCR |= CPM_CFCR_UPE
|
||||||
#elif defined (NANONOTE)
|
#elif defined (NANONOTE)
|
||||||
unsigned val = cpm_get_pllout2 () / pclk - 1
|
unsigned val = cpm_get_pllout2 () / pixclock - 1
|
||||||
if val > 0x3ff:
|
kdebug_num (val)
|
||||||
kdebug ("pixel clock too large\n")
|
kdebug ("\n")
|
||||||
Kernel::panic ()
|
assert (val < 0x400)
|
||||||
return
|
|
||||||
cpm_set_pixdiv (val);
|
cpm_set_pixdiv (val);
|
||||||
|
|
||||||
val = cpm_get_pllout () / (pixclock * 3)
|
val = cpm_get_pllout () / (pixclock * 3)
|
||||||
if val > 0x1f:
|
assert (val < 0x20)
|
||||||
kdebug ("pixel divider too large\n")
|
|
||||||
Kernel::panic ()
|
|
||||||
return
|
|
||||||
cpm_set_ldiv (val)
|
cpm_set_ldiv (val)
|
||||||
// Update dividers.
|
// Update dividers.
|
||||||
CPM_CPCCR |= CPM_CPCCR_CE
|
CPM_CPCCR |= CPM_CPCCR_CE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
cpm_start_lcd ()
|
cpm_start_lcd ()
|
||||||
|
|
||||||
LCD_DA0 = physical_descriptor
|
LCD_DA0 = physical_descriptor
|
||||||
lcd_set_ena ()
|
lcd_set_ena ()
|
||||||
lcd_enable_eof_intr ()
|
//lcd_enable_eof_intr ()
|
||||||
|
|
||||||
|
#ifdef NANONOTE
|
||||||
|
// Reset registers.
|
||||||
|
write_reg (BACKLIGHT1, 0)
|
||||||
|
// Enable display.
|
||||||
|
write_reg (BACKLIGHT1, 0x5f)
|
||||||
|
#endif
|
||||||
|
|
||||||
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:
|
||||||
@ -170,9 +238,16 @@ static void log_msg ():
|
|||||||
log_num (Kernel::recv.data[i])
|
log_num (Kernel::recv.data[i])
|
||||||
log_char ('\n')
|
log_char ('\n')
|
||||||
|
|
||||||
|
enum captype:
|
||||||
|
LOG
|
||||||
|
SET_EOF_CB
|
||||||
|
|
||||||
Kernel::Num start ():
|
Kernel::Num start ():
|
||||||
map_lcd ()
|
map_lcd ()
|
||||||
map_cpm ()
|
map_cpm ()
|
||||||
|
#ifdef NANONOTE
|
||||||
|
map_gpio ()
|
||||||
|
#endif
|
||||||
|
|
||||||
Descriptor descriptor __attribute__ ((aligned (16)))
|
Descriptor descriptor __attribute__ ((aligned (16)))
|
||||||
unsigned pages = (frame_size + ~PAGE_MASK) >> PAGE_BITS
|
unsigned pages = (frame_size + ~PAGE_MASK) >> PAGE_BITS
|
||||||
@ -184,23 +259,22 @@ Kernel::Num start ():
|
|||||||
Kernel::my_memory.map (p, (unsigned)LCD_FRAMEBUFFER_BASE + i * PAGE_SIZE)
|
Kernel::my_memory.map (p, (unsigned)LCD_FRAMEBUFFER_BASE + i * PAGE_SIZE)
|
||||||
Kernel::free_cap (p)
|
Kernel::free_cap (p)
|
||||||
for unsigned y = 0; y < v; ++y:
|
for unsigned y = 0; y < v; ++y:
|
||||||
unsigned g = (y << 6) / v
|
unsigned g = (y << 8) / v
|
||||||
unsigned olr = 0, ob = ((25 * y * y) << 5) / (9 * h * h + 25 * v * v)
|
|
||||||
for unsigned x = 0; x < h; ++x:
|
for unsigned x = 0; x < h; ++x:
|
||||||
unsigned r = (x << 5) / h
|
unsigned r = (x << 8) / h
|
||||||
unsigned b = ((9 * x * x + 25 * y * y) << 5) / (9 * h * h + 25 * v * v)
|
unsigned b = ((x + y) << 8) / (h + v)
|
||||||
if r != olr:
|
#if defined (TRENDTAC)
|
||||||
olr = r
|
LCD_FRAMEBUFFER_BASE[y * h + x] = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3)
|
||||||
r = 0x1f
|
#elif defined (NANONOTE)
|
||||||
unsigned oyb = b
|
LCD_FRAMEBUFFER_BASE[(y * h + x) * Bpp + 2] = r
|
||||||
if y > 0:
|
LCD_FRAMEBUFFER_BASE[(y * h + x) * Bpp + 1] = g
|
||||||
oyb = ((9 * x * x + 25 * (y - 1) * (y - 1)) << 5) / (9 * h * h + 25 * v * v)
|
LCD_FRAMEBUFFER_BASE[(y * h + x) * Bpp + 0] = b
|
||||||
if b != ob || b != oyb:
|
#else
|
||||||
ob = b
|
#error "Define your framebuffer format."
|
||||||
b = 0x1f
|
#endif
|
||||||
LCD_FRAMEBUFFER_BASE[y * h + x] = (r << 11) | (g << 5) | (b)
|
|
||||||
Kernel::Page p = Kernel::my_memory.mapping (&descriptor)
|
Kernel::Page p = Kernel::my_memory.mapping (&descriptor)
|
||||||
physical_descriptor = p.physical_address () + ((unsigned)&descriptor & ~PAGE_MASK)
|
unsigned paddr = p.physical_address ()
|
||||||
|
physical_descriptor = paddr + ((unsigned)&descriptor & ~PAGE_MASK)
|
||||||
Kernel::free_cap (p)
|
Kernel::free_cap (p)
|
||||||
descriptor.next = physical_descriptor
|
descriptor.next = physical_descriptor
|
||||||
descriptor.frame = physical
|
descriptor.frame = physical
|
||||||
@ -210,7 +284,7 @@ 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 (Init::LCD_LOG)
|
Kernel::Cap logcap = Kernel::my_receiver.create_capability (LOG)
|
||||||
#if defined (TRENDTAC)
|
#if defined (TRENDTAC)
|
||||||
__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
|
||||||
@ -225,7 +299,7 @@ Kernel::Num start ():
|
|||||||
lcd_clr_eof ()
|
lcd_clr_eof ()
|
||||||
eof_cb.invoke ()
|
eof_cb.invoke ()
|
||||||
break
|
break
|
||||||
case Init::LCD_SET_EOF_CB:
|
case SET_EOF_CB:
|
||||||
if have_eof:
|
if have_eof:
|
||||||
Kernel::free_cap (eof_cb)
|
Kernel::free_cap (eof_cb)
|
||||||
else:
|
else:
|
||||||
@ -236,7 +310,7 @@ Kernel::Num start ():
|
|||||||
reply.invoke ()
|
reply.invoke ()
|
||||||
Kernel::free_cap (reply)
|
Kernel::free_cap (reply)
|
||||||
break
|
break
|
||||||
case Init::LCD_LOG:
|
case LOG:
|
||||||
log_char (Kernel::recv.data[0].l)
|
log_char (Kernel::recv.data[0].l)
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
|
@ -25,10 +25,11 @@ Kernel::Num start ():
|
|||||||
Keyboard kbd = Kernel::my_parent.get_device <Keyboard> ()
|
Keyboard kbd = Kernel::my_parent.get_device <Keyboard> ()
|
||||||
Kernel::Cap key = Kernel::my_receiver.create_capability (0)
|
Kernel::Cap key = Kernel::my_receiver.create_capability (0)
|
||||||
kbd.set_cb (key)
|
kbd.set_cb (key)
|
||||||
|
// Frequency of the pulse train in millihertz.
|
||||||
unsigned mHz = 1000
|
unsigned mHz = 1000
|
||||||
|
// Frequency of single pulses in hertz.
|
||||||
unsigned freq = 1000
|
unsigned freq = 1000
|
||||||
Kernel::my_receiver.set_alarm (1)
|
bool running (false)
|
||||||
bool running (true)
|
|
||||||
while true:
|
while true:
|
||||||
Kernel::wait ()
|
Kernel::wait ()
|
||||||
switch Kernel::recv.protected_data.l:
|
switch Kernel::recv.protected_data.l:
|
||||||
@ -48,10 +49,10 @@ Kernel::Num start ():
|
|||||||
freq = freq * 9 / 10
|
freq = freq * 9 / 10
|
||||||
break
|
break
|
||||||
case Key::LEFT:
|
case Key::LEFT:
|
||||||
mHz = mHz * 101 / 100
|
mHz = mHz * 99 / 100
|
||||||
break
|
break
|
||||||
case Key::RIGHT:
|
case Key::RIGHT:
|
||||||
mHz = mHz * 99 / 100
|
mHz = mHz * 101 / 100
|
||||||
break
|
break
|
||||||
case Key::UP:
|
case Key::UP:
|
||||||
mHz = mHz * 11 / 10
|
mHz = mHz * 11 / 10
|
||||||
@ -62,7 +63,7 @@ Kernel::Num start ():
|
|||||||
case Key::P:
|
case Key::P:
|
||||||
running = !running
|
running = !running
|
||||||
if running:
|
if running:
|
||||||
Kernel::my_receiver.set_alarm (1)
|
Kernel::my_receiver.set_alarm (0)
|
||||||
break
|
break
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
|
@ -202,8 +202,8 @@ Kernel::Num start ():
|
|||||||
|
|
||||||
Device dev = Kernel::my_receiver.create_capability (KBD_DEV)
|
Device dev = Kernel::my_receiver.create_capability (KBD_DEV)
|
||||||
Keyboard pw = Kernel::my_receiver.create_capability (PWR)
|
Keyboard pw = Kernel::my_receiver.create_capability (PWR)
|
||||||
Kernel::my_parent.ocall (dev.copy (), Kernel::Num (Keyboard::ID, 0))
|
Kernel::my_parent.provide_device <Keyboard> (dev.copy (), 0)
|
||||||
Kernel::my_parent.ocall (pw.copy (), Kernel::Num (Keyboard::ID, 1))
|
Kernel::my_parent.provide_device <Keyboard> (pw.copy (), 1)
|
||||||
Kernel::free_cap (dev)
|
Kernel::free_cap (dev)
|
||||||
Kernel::free_cap (pw)
|
Kernel::free_cap (pw)
|
||||||
if kbd.scanning ():
|
if kbd.scanning ():
|
||||||
|
47
clocks.txt
Normal file
47
clocks.txt
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
cclk: cpu clock. Fastest clock in the system.
|
||||||
|
hclk: high-speed peripheral bus clock.
|
||||||
|
pclk: peripheral bus clock.
|
||||||
|
mclk: memory clock, for emc.
|
||||||
|
ldclk: lcd device clock.
|
||||||
|
lpclk: lcd pixel clock.
|
||||||
|
cim_mclk: clock output for cim.
|
||||||
|
cim_pclk: clock input for cim.
|
||||||
|
i2sclk: codec clock.
|
||||||
|
mscclk: msc clock.
|
||||||
|
ssiclk: ssi clock.
|
||||||
|
exclk: 12MHz clock output, used by uart, i2c, ssi, tcu, usb2.0-phy.
|
||||||
|
rtclk: 32768Hz clock input for rtc.
|
||||||
|
|
||||||
|
cclk: 252M
|
||||||
|
hclk: 84M
|
||||||
|
pclk: 84M
|
||||||
|
mclk: 84M
|
||||||
|
ldclk: 84M; must not be larger than 150M
|
||||||
|
lpclk: 25295340 (70Hz screen refresh)
|
||||||
|
cim_mclk: not used.
|
||||||
|
cim_pclk: not used.
|
||||||
|
i2sclk: must be 12M
|
||||||
|
mscclk: must not be larger than 400k during init; not larger than 25M later.
|
||||||
|
ssiclk: not used.
|
||||||
|
exclk: 12M, not adjustable.
|
||||||
|
rtclk: 32768, not adjustable.
|
||||||
|
|
||||||
|
usb clock, for host and device, must be 48M.
|
||||||
|
|
||||||
|
restrictions:
|
||||||
|
- cclk must be i*hclk
|
||||||
|
- i must not be 24 or 32
|
||||||
|
- hclk = mclk or hclk = 2*mclk
|
||||||
|
- mclk = k*pclk
|
||||||
|
|
||||||
|
so:
|
||||||
|
- pclk is set
|
||||||
|
- mclk = k*pclk
|
||||||
|
- hclk = l*mclk = l*k*pclk; l = 1 or 2
|
||||||
|
- cclk = i*hclk = i*l*k*pclk; i != 24 or 32
|
||||||
|
|
||||||
|
In the code:
|
||||||
|
m = 42
|
||||||
|
n = 2
|
||||||
|
no = 1
|
||||||
|
So clkout = 12M * 21 = 252M; this is the pll clock frequency.
|
101
devices.hhp
101
devices.hhp
@ -75,26 +75,11 @@ struct WString : public String:
|
|||||||
void set_page (Kernel::Num idx, Kernel::Page page):
|
void set_page (Kernel::Num idx, Kernel::Page page):
|
||||||
ocall (page, CAP_MASTER_DIRECT | SET_PAGE, idx)
|
ocall (page, CAP_MASTER_DIRECT | SET_PAGE, idx)
|
||||||
|
|
||||||
// Interface for talking to the parent process.
|
|
||||||
struct Parent : public Kernel::Cap:
|
|
||||||
Parent (Kernel::Cap c = Kernel::Cap ()) : Kernel::Cap (c):
|
|
||||||
enum request:
|
|
||||||
GET_DEVICE = WString::ID
|
|
||||||
EXIT
|
|
||||||
ID
|
|
||||||
// Get a device handle.
|
|
||||||
template <typename _T> _T get_device (unsigned num = 0):
|
|
||||||
icall (CAP_MASTER_DIRECT | GET_DEVICE, Kernel::Num (_T::ID, num))
|
|
||||||
return Kernel::get_arg ()
|
|
||||||
// Exit the program. The parent does not reply, but kills the process.
|
|
||||||
void exit (Kernel::Num code):
|
|
||||||
call (CAP_MASTER_DIRECT | EXIT, code)
|
|
||||||
|
|
||||||
// Every process which wants to be switchable through a terminal must implement this interface.
|
// Every process which wants to be switchable through a terminal must implement this interface.
|
||||||
struct Device : public Kernel::Cap:
|
struct Device : public Kernel::Cap:
|
||||||
Device (Kernel::Cap c = Kernel::Cap ()) : Kernel::Cap (c):
|
Device (Kernel::Cap c = Kernel::Cap ()) : Kernel::Cap (c):
|
||||||
enum request:
|
enum request:
|
||||||
CREATE_USER = Parent::ID
|
CREATE_USER = WString::ID
|
||||||
DESTROY_USER
|
DESTROY_USER
|
||||||
UNUSE
|
UNUSE
|
||||||
USE
|
USE
|
||||||
@ -114,11 +99,40 @@ struct Device : public Kernel::Cap:
|
|||||||
void use (Kernel::Cap user):
|
void use (Kernel::Cap user):
|
||||||
ocall (user, CAP_MASTER_DIRECT | USE)
|
ocall (user, CAP_MASTER_DIRECT | USE)
|
||||||
|
|
||||||
|
// Interface for talking to the parent process.
|
||||||
|
struct Parent : public Kernel::Cap:
|
||||||
|
Parent (Kernel::Cap c = Kernel::Cap ()) : Kernel::Cap (c):
|
||||||
|
enum request:
|
||||||
|
GET_DEVICE = Device::ID
|
||||||
|
PROVIDE_DEVICE
|
||||||
|
GET_MEMORY
|
||||||
|
PROVIDE_MEMORY
|
||||||
|
EXIT
|
||||||
|
ID
|
||||||
|
// Get a device handle.
|
||||||
|
template <typename _T> _T get_device (unsigned num = 0):
|
||||||
|
icall (Kernel::Num (CAP_MASTER_DIRECT | GET_DEVICE, num), _T::ID)
|
||||||
|
return Kernel::get_arg ()
|
||||||
|
// Provide a device handle.
|
||||||
|
template <typename _T> void provide_device (Device dev, unsigned num = 0):
|
||||||
|
ocall (dev, Kernel::Num (CAP_MASTER_DIRECT | PROVIDE_DEVICE, num), _T::ID)
|
||||||
|
// Get memory paid for by another thread, which cannot be inspected or changed by that thread. The memory can be inspected and changed by the user (owning both threads). The call will fail when the threads are not owned by the same user.
|
||||||
|
Kernel::Memory get_memory (Kernel::Cap target):
|
||||||
|
iocall (target, CAP_MASTER_DIRECT | GET_MEMORY)
|
||||||
|
return Kernel::get_arg ()
|
||||||
|
// Get a handle that another thread can use to call get_memory on. The actual limit on the created memory is floor(limit, thread address space limit).
|
||||||
|
Kernel::Cap provide_memory (unsigned limit):
|
||||||
|
icall (CAP_MASTER_DIRECT | PROVIDE_MEMORY, limit)
|
||||||
|
return Kernel::get_arg ()
|
||||||
|
// Exit the program. The parent does not reply, but kills the process.
|
||||||
|
void exit (Kernel::Num code):
|
||||||
|
call (CAP_MASTER_DIRECT | EXIT, code)
|
||||||
|
|
||||||
// Keyboard interface.
|
// Keyboard interface.
|
||||||
struct Keyboard : public Kernel::Cap:
|
struct Keyboard : public Kernel::Cap:
|
||||||
Keyboard (Kernel::Cap c = Kernel::Cap ()) : Kernel::Cap (c):
|
Keyboard (Kernel::Cap c = Kernel::Cap ()) : Kernel::Cap (c):
|
||||||
enum request:
|
enum request:
|
||||||
SET_CB = Device::ID
|
SET_CB = Parent::ID
|
||||||
GET_NUM_KEYS
|
GET_NUM_KEYS
|
||||||
GET_KEYS
|
GET_KEYS
|
||||||
ID
|
ID
|
||||||
@ -178,36 +192,23 @@ struct Display : public Kernel::Cap:
|
|||||||
|
|
||||||
|
|
||||||
// File system interface.
|
// File system interface.
|
||||||
// filesystem-related interfaces: file, directory, stream, seekable, mappable.
|
// filesystem-related interfaces: directory, stream, seekable, mappable.
|
||||||
// Normal files implement at least stream or seekable file. Directories implement directory.
|
// Normal files implement at least stream or seekable file. Directories implement directory.
|
||||||
struct File : public Kernel::Cap:
|
|
||||||
File (Kernel::Cap c = Kernel::Cap ()) : Kernel::Cap (c):
|
|
||||||
enum request:
|
|
||||||
INFO = Display::ID
|
|
||||||
CLOSE
|
|
||||||
MAP_HANDLE
|
|
||||||
ID
|
|
||||||
// Get information about the file.
|
|
||||||
Kernel::Num get_info (unsigned type):
|
|
||||||
return icall (Kernel::Num (CAP_MASTER_DIRECT | INFO, type))
|
|
||||||
// Close a file. If this is a directory, it implicitly closes all files opened from it.
|
|
||||||
void close ():
|
|
||||||
call (CAP_MASTER_DIRECT | CLOSE)
|
|
||||||
// Map a file handle. This can be useful for closing all children at once. The new handle itself is a child of the original handle.
|
|
||||||
File map_handle ():
|
|
||||||
icall (CAP_MASTER_DIRECT | MAP_HANDLE)
|
|
||||||
return Kernel::get_arg ()
|
|
||||||
|
|
||||||
// Directory interface.
|
// Directory interface.
|
||||||
struct Directory : public File:
|
struct Directory : public Kernel::Cap:
|
||||||
Directory (Kernel::Cap c = Kernel::Cap ()) : File (c):
|
Directory (Kernel::Cap c = Kernel::Cap ()) : Kernel::Cap (c):
|
||||||
enum request:
|
enum request:
|
||||||
GET_SIZE = File::ID
|
GET_SIZE = Display::ID
|
||||||
GET_NAME
|
GET_NAME
|
||||||
GET_FILE
|
GET_FILE
|
||||||
GET_FILE_INFO
|
GET_FILE_INFO
|
||||||
CREATE_FILE
|
CREATE_FILE
|
||||||
DELETE_FILE
|
DELETE_FILE
|
||||||
|
LOCK
|
||||||
|
UNLOCK
|
||||||
|
LOCK_RO
|
||||||
|
UNLOCK_RO
|
||||||
ID
|
ID
|
||||||
// Get the number of entries in this directory.
|
// Get the number of entries in this directory.
|
||||||
Kernel::Num get_size ():
|
Kernel::Num get_size ():
|
||||||
@ -217,23 +218,35 @@ struct Directory : public File:
|
|||||||
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.
|
||||||
File 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.
|
// 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):
|
Kernel::Num get_file_info (Kernel::Num idx, unsigned type):
|
||||||
return icall (Kernel::Num (CAP_MASTER_DIRECT | GET_FILE_INFO, type), idx)
|
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.
|
||||||
File create_file (String name):
|
Kernel::Cap create_file (String name):
|
||||||
icall (CAP_MASTER_DIRECT | CREATE_FILE)
|
icall (CAP_MASTER_DIRECT | CREATE_FILE)
|
||||||
return Kernel::get_arg ()
|
return Kernel::get_arg ()
|
||||||
// Delete a file. After this, any index may map to a different file.
|
// Delete a file. After this, any index may map to a different file.
|
||||||
void delete_file (Kernel::Num idx):
|
void delete_file (Kernel::Num idx):
|
||||||
call (CAP_MASTER_DIRECT | DELETE_FILE, idx)
|
call (CAP_MASTER_DIRECT | DELETE_FILE, idx)
|
||||||
|
// Lock the directory. Write operations can only be done when the directory is locked.
|
||||||
|
void lock ():
|
||||||
|
call (CAP_MASTER_DIRECT | LOCK)
|
||||||
|
// 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.
|
// Stream interface.
|
||||||
struct Stream : public File:
|
struct Stream : public Kernel::Cap:
|
||||||
Stream (Kernel::Cap c = Kernel::Cap ()) : File (c):
|
Stream (Kernel::Cap c = Kernel::Cap ()) : Kernel::Cap (c):
|
||||||
enum request:
|
enum request:
|
||||||
READ = Directory::ID
|
READ = Directory::ID
|
||||||
WRITE
|
WRITE
|
||||||
@ -246,8 +259,8 @@ struct Stream : public File:
|
|||||||
return ocall (s, CAP_MASTER_DIRECT | WRITE, size)
|
return ocall (s, CAP_MASTER_DIRECT | WRITE, size)
|
||||||
|
|
||||||
// Seekable file interface.
|
// Seekable file interface.
|
||||||
struct Seekable : public File:
|
struct Seekable : public Kernel::Cap:
|
||||||
Seekable (Kernel::Cap c = Kernel::Cap ()) : File (c):
|
Seekable (Kernel::Cap c = Kernel::Cap ()) : Kernel::Cap (c):
|
||||||
enum request:
|
enum request:
|
||||||
READ = Stream::ID
|
READ = Stream::ID
|
||||||
WRITE
|
WRITE
|
||||||
|
@ -225,7 +225,7 @@ static void receiver_invoke (unsigned cmd, unsigned target, Kernel::Num protecte
|
|||||||
case Kernel::Receiver::SET_ALARM & REQUEST_MASK:
|
case Kernel::Receiver::SET_ALARM & REQUEST_MASK:
|
||||||
case Kernel::Receiver::ADD_ALARM & REQUEST_MASK:
|
case Kernel::Receiver::ADD_ALARM & REQUEST_MASK:
|
||||||
unsigned old = receiver->alarm_count
|
unsigned old = receiver->alarm_count
|
||||||
if cmd == Kernel::Receiver::SET_ALARM & REQUEST_MASK:
|
if cmd == (Kernel::Receiver::SET_ALARM & REQUEST_MASK):
|
||||||
receiver->alarm_count = c->data[1].l
|
receiver->alarm_count = c->data[1].l
|
||||||
else:
|
else:
|
||||||
receiver->alarm_count += c->data[1].l
|
receiver->alarm_count += c->data[1].l
|
||||||
|
2
iris.hhp
2
iris.hhp
@ -497,7 +497,7 @@ namespace Kernel:
|
|||||||
// The start function has this prototype (there is no main function).
|
// The start function has this prototype (there is no main function).
|
||||||
Kernel::Num start ()
|
Kernel::Num start ()
|
||||||
|
|
||||||
#if 1
|
#if 1 && !defined (__KERNEL__)
|
||||||
// Use a define instead of an inline function, because this is better visible in disassembly, even when not optimizing.
|
// Use a define instead of an inline function, because this is better visible in disassembly, even when not optimizing.
|
||||||
#define kdebug_char(c) do { unsigned d = (c); __asm__ volatile ("move $a0, $zero\nlw $a1, %0\nbreak" :: "m"(d) : "a0", "a1", "memory"); } while (0)
|
#define kdebug_char(c) do { unsigned d = (c); __asm__ volatile ("move $a0, $zero\nlw $a1, %0\nbreak" :: "m"(d) : "a0", "a1", "memory"); } while (0)
|
||||||
#else
|
#else
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
#define _KERNEL_HH
|
#define _KERNEL_HH
|
||||||
|
|
||||||
// Include definitions which are shared with user space.
|
// Include definitions which are shared with user space.
|
||||||
#define __KERNEL
|
#define __KERNEL__
|
||||||
#include "iris.hh"
|
#include "iris.hh"
|
||||||
|
|
||||||
// Normally define all variables in this file as extern.
|
// Normally define all variables in this file as extern.
|
||||||
|
@ -1 +1 @@
|
|||||||
board/Makefile.arch
|
nanonote/Makefile.arch
|
@ -185,6 +185,7 @@ static unsigned make_entry_lo (kPage *page, bool readonly):
|
|||||||
if page->flags & Kernel::Page::UNCACHED:
|
if page->flags & Kernel::Page::UNCACHED:
|
||||||
flags = 0x10 | 0x2
|
flags = 0x10 | 0x2
|
||||||
else:
|
else:
|
||||||
|
// 18 is write-back cache; 00 is write-through cache.
|
||||||
flags = 0x18 | 0x2
|
flags = 0x18 | 0x2
|
||||||
if !readonly:
|
if !readonly:
|
||||||
flags |= 0x4
|
flags |= 0x4
|
||||||
@ -289,15 +290,3 @@ void arch_register_interrupt (unsigned num, kReceiver *r):
|
|||||||
intc_unmask_irq (num)
|
intc_unmask_irq (num)
|
||||||
else:
|
else:
|
||||||
intc_mask_irq (num)
|
intc_mask_irq (num)
|
||||||
|
|
||||||
void arch_reboot ():
|
|
||||||
// Wait for serial port to be done.
|
|
||||||
while !(UART0_LSR & UARTLSR_TEMT):
|
|
||||||
// Reboot.
|
|
||||||
wdt_select_extalclk ()
|
|
||||||
wdt_select_clk_div1 ()
|
|
||||||
wdt_set_data (1)
|
|
||||||
wdt_set_count (0)
|
|
||||||
wdt_start ()
|
|
||||||
// Wait for wdt to trigger reboot.
|
|
||||||
while true:
|
|
||||||
|
@ -69,7 +69,7 @@
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __KERNEL
|
#ifdef __KERNEL__
|
||||||
// register save positions in kThread
|
// register save positions in kThread
|
||||||
#define SAVE_PC (6 * 4)
|
#define SAVE_PC (6 * 4)
|
||||||
#define SAVE_SP (SAVE_PC + 4)
|
#define SAVE_SP (SAVE_PC + 4)
|
||||||
@ -147,6 +147,6 @@ extern unsigned **directory
|
|||||||
|
|
||||||
#endif // not defined ASM
|
#endif // not defined ASM
|
||||||
|
|
||||||
#endif // defined __KERNEL
|
#endif // defined __KERNEL__
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
#define ARCH
|
#define ARCH
|
||||||
#define ASM
|
#define ASM
|
||||||
#define __KERNEL
|
#define __KERNEL__
|
||||||
#include "arch.hh"
|
#include "arch.hh"
|
||||||
|
|
||||||
addr_000:
|
addr_000:
|
||||||
@ -118,7 +118,7 @@ start_idle: // 280
|
|||||||
// TODO: save only fragile registers now, the rest on task switch.
|
// TODO: save only fragile registers now, the rest on task switch.
|
||||||
kernel_exit:
|
kernel_exit:
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
// Interrupts were enabled in the kernel; set them to usermode setting again.
|
// Exceptions were enabled in the kernel; set them to usermode setting again.
|
||||||
mfc0 $k0, $CP0_STATUS
|
mfc0 $k0, $CP0_STATUS
|
||||||
ori $k0, $k0, 0xff13
|
ori $k0, $k0, 0xff13
|
||||||
mtc0 $k0, $CP0_STATUS
|
mtc0 $k0, $CP0_STATUS
|
||||||
@ -217,7 +217,7 @@ save_regs:
|
|||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
// Allow kernel bugs to set EPC and friends.
|
// Allow kernel bugs to set EPC and friends.
|
||||||
mfc0 $k0, $CP0_STATUS
|
mfc0 $k0, $CP0_STATUS
|
||||||
li $k1, 0x1000ff00
|
li $k1, 0x10000000
|
||||||
and $k0, $k0, $k1
|
and $k0, $k0, $k1
|
||||||
mtc0 $k0, $CP0_STATUS
|
mtc0 $k0, $CP0_STATUS
|
||||||
#endif
|
#endif
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
load = 0x80000000
|
load = 0x80000000
|
||||||
|
|
||||||
ARCH_CXXFLAGS = -DNUM_THREADS=5
|
ARCH_CXXFLAGS = -DNUM_THREADS=6
|
||||||
ARCH_CPPFLAGS = -I. -Imips -Imips/nanonote -Wa,-mips32 -DNANONOTE -DUSE_SERIAL
|
ARCH_CPPFLAGS = -I. -Imips -Imips/nanonote -Wa,-mips32 -DNANONOTE -DUSE_SERIAL
|
||||||
CROSS = mipsel-linux-gnu-
|
CROSS = mipsel-linux-gnu-
|
||||||
OBJDUMP = $(CROSS)objdump
|
OBJDUMP = $(CROSS)objdump
|
||||||
@ -28,7 +28,7 @@ LDFLAGS = --omagic -Ttext $(load)
|
|||||||
arch_iris_sources = mips/interrupts.cc mips/arch.cc
|
arch_iris_sources = mips/interrupts.cc mips/arch.cc
|
||||||
boot_sources = mips/init.cc mips/nanonote/board.cc
|
boot_sources = mips/init.cc mips/nanonote/board.cc
|
||||||
arch_headers = mips/arch.hh mips/nanonote/jz4740.hh mips/nanonote/board.hh
|
arch_headers = mips/arch.hh mips/nanonote/jz4740.hh mips/nanonote/board.hh
|
||||||
boot_threads = init udc nanonote-gpio buzzer metronome
|
boot_threads = init udc nanonote-gpio buzzer metronome lcd
|
||||||
|
|
||||||
test: iris.raw nanonote-boot
|
test: iris.raw nanonote-boot
|
||||||
./nanonote-boot iris.raw 0xa$(shell /bin/sh -c '$(OBJDUMP) -t iris.elf | grep __start$$ | cut -b2-8')
|
./nanonote-boot iris.raw 0xa$(shell /bin/sh -c '$(OBJDUMP) -t iris.elf | grep __start$$ | cut -b2-8')
|
||||||
@ -46,10 +46,10 @@ 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/boot.o: TARGET_FLAGS = -DMEMORY_SIZE="32 << 20"
|
mips/boot.o: TARGET_FLAGS = -DMEMORY_SIZE="32 << 20"
|
||||||
mips/entry.o: $(boot_threads)
|
mips/entry.o: $(addsuffix .elf,$(boot_threads))
|
||||||
mips/init.o: TARGET_FLAGS = -I/usr/include
|
mips/init.o: TARGET_FLAGS = -I/usr/include
|
||||||
$(boot_threads): TARGET_FLAGS = -I.
|
$(addsuffix .elf,$(boot_threads)): TARGET_FLAGS = -I.
|
||||||
$(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: boot-programs/charset.data
|
||||||
|
|
||||||
@ -63,4 +63,4 @@ boot-programs/charset.data: boot-programs/charset
|
|||||||
iris.elf: mips/entry.o $(subst .cc,.o,$(iris_sources)) mips/nanonote/threadlist.o mips/boot.o $(subst .cc,.o,$(boot_sources))
|
iris.elf: mips/entry.o $(subst .cc,.o,$(iris_sources)) mips/nanonote/threadlist.o mips/boot.o $(subst .cc,.o,$(boot_sources))
|
||||||
$(LD) $(LDFLAGS) $^ -o $@
|
$(LD) $(LDFLAGS) $^ -o $@
|
||||||
|
|
||||||
ARCH_CLEAN_FILES = $(boot_sources) $(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
|
||||||
|
@ -27,9 +27,15 @@ void board_init ():
|
|||||||
gpio_as_sdram_16bit ()
|
gpio_as_sdram_16bit ()
|
||||||
gpio_as_nand ()
|
gpio_as_nand ()
|
||||||
gpio_as_aic ()
|
gpio_as_aic ()
|
||||||
gpio_as_lcd_16bit ()
|
|
||||||
gpio_as_msc ()
|
gpio_as_msc ()
|
||||||
|
gpio_as_lcd_16bit ()
|
||||||
|
// Set up memory.
|
||||||
setup_sdram ()
|
setup_sdram ()
|
||||||
|
// Use some gpio pins for lcd.
|
||||||
|
gpio_as_gpio (2, (1 << 21) | (1 << 22) | (1 << 23))
|
||||||
|
gpio_as_gpio (3, 1 << 27)
|
||||||
|
gpio_as_output (2, (1 << 21) | (1 << 22) | (1 << 23))
|
||||||
|
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)
|
||||||
tcu_stop_counter (0)
|
tcu_stop_counter (0)
|
||||||
@ -56,3 +62,15 @@ 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")
|
||||||
|
|
||||||
|
void arch_reboot ():
|
||||||
|
// Wait for serial port to be done.
|
||||||
|
while !(UART0_LSR & UARTLSR_TEMT):
|
||||||
|
// Reboot.
|
||||||
|
wdt_select_extalclk ()
|
||||||
|
wdt_select_clk_div1 ()
|
||||||
|
wdt_set_data (1)
|
||||||
|
wdt_set_count (0)
|
||||||
|
wdt_start ()
|
||||||
|
// Wait for wdt to trigger reboot.
|
||||||
|
while true:
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
#define __JZ4740_HH__
|
#define __JZ4740_HH__
|
||||||
|
|
||||||
// Main clock, for cpu, serial port, and with divisors for most other hardware
|
// Main clock, for cpu, serial port, and with divisors for most other hardware
|
||||||
#define JZ_EXTAL 12000000 /* 3.6864 MHz */
|
#define JZ_EXTAL 12000000 /* 12 MHz */
|
||||||
// RTC clock
|
// RTC clock
|
||||||
#define RTC_CLOCK 32768 /* 32.768 KHz */
|
#define RTC_CLOCK 32768 /* 32.768 KHz */
|
||||||
// Interrupt source used for system timer
|
// Interrupt source used for system timer
|
||||||
@ -50,7 +50,7 @@
|
|||||||
#define CIM_PHYSICAL 0x13060000
|
#define CIM_PHYSICAL 0x13060000
|
||||||
#define ETH_PHYSICAL 0x13100000
|
#define ETH_PHYSICAL 0x13100000
|
||||||
|
|
||||||
#ifdef __KERNEL
|
#ifdef __KERNEL__
|
||||||
// In kernel space you need to add 0xa0000000 to see them unmapped uncached in kseg2.
|
// In kernel space you need to add 0xa0000000 to see them unmapped uncached in kseg2.
|
||||||
#define CPM_BASE (0xa0000000 + CPM_PHYSICAL)
|
#define CPM_BASE (0xa0000000 + CPM_PHYSICAL)
|
||||||
#define INTC_BASE (0xa0000000 + INTC_PHYSICAL)
|
#define INTC_BASE (0xa0000000 + INTC_PHYSICAL)
|
||||||
@ -102,7 +102,7 @@
|
|||||||
#define ETH_BASE 0x00014000
|
#define ETH_BASE 0x00014000
|
||||||
|
|
||||||
// Default lcd framebuffer mapping space.
|
// Default lcd framebuffer mapping space.
|
||||||
#define LCD_FRAMEBUFFER_BASE ((unsigned short *)0x00015000)
|
#define LCD_FRAMEBUFFER_BASE ((unsigned char *)0x00015000)
|
||||||
|
|
||||||
// Map IO memory (requires a priviledged Kernel::my_thread capability).
|
// Map IO memory (requires a priviledged Kernel::my_thread capability).
|
||||||
#include <iris.hh>
|
#include <iris.hh>
|
||||||
@ -2346,17 +2346,18 @@ static void gpio_disable_pull (unsigned p, unsigned pins):
|
|||||||
// CPM
|
// CPM
|
||||||
//**************************************************************************
|
//**************************************************************************
|
||||||
static void pll_init ():
|
static void pll_init ():
|
||||||
unsigned PHM_DIV = 3
|
// The cpu clock is set to 252 MHz
|
||||||
unsigned int cfcr, plcr1
|
unsigned const cpu_clock = 252000000
|
||||||
int n2FR[33] = { 0, 0, 1, 2, 3, 0, 4, 0, 5, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 9 }
|
// The usb clock must be 48 MHz
|
||||||
int nf, pllout2;
|
unsigned const usb_clock = 48000000
|
||||||
cfcr = CPM_CPCCR_CLKOEN | (n2FR[1] << CPM_CPCCR_CDIV_BIT) | (n2FR[PHM_DIV] << CPM_CPCCR_HDIV_BIT) | (n2FR[PHM_DIV] << CPM_CPCCR_PDIV_BIT) | (n2FR[PHM_DIV] << CPM_CPCCR_MDIV_BIT) | (n2FR[PHM_DIV] << CPM_CPCCR_LDIV_BIT)
|
// ssi clock must be 12 MHz, therefore it is taken directly from JZ_EXTAL, not from divided pll output.
|
||||||
pllout2 = (cfcr & CPM_CPCCR_PCS) ? 252000000 : (252000000 / 2)
|
|
||||||
CPM_UHCCDR = pllout2 / 48000000 - 1
|
// USB clock must be 48 MHz.
|
||||||
nf = 252000000 * 2 / JZ_EXTAL
|
CPM_UHCCDR = (cpu_clock / 2) / usb_clock - 1
|
||||||
plcr1 = ((nf - 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.
|
||||||
CPM_CPCCR = cfcr
|
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)
|
||||||
CPM_CPPCR = plcr1
|
// 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
|
||||||
|
|
||||||
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
|
||||||
@ -2388,32 +2389,32 @@ static unsigned cpm_get_uhcdiv ():
|
|||||||
static unsigned cpm_get_ssidiv ():
|
static unsigned cpm_get_ssidiv ():
|
||||||
return (CPM_SSICDR & CPM_SSICDR_SSIDIV_MASK) >> CPM_SSICDR_SSIDIV_BIT
|
return (CPM_SSICDR & CPM_SSICDR_SSIDIV_MASK) >> CPM_SSICDR_SSIDIV_BIT
|
||||||
|
|
||||||
static unsigned cpm_set_cdiv (unsigned v):
|
static void cpm_set_cdiv (unsigned v):
|
||||||
return CPM_CPCCR = (CPM_CPCCR & ~CPM_CPCCR_CDIV_MASK) | (v << (CPM_CPCCR_CDIV_BIT))
|
CPM_CPCCR = (CPM_CPCCR & ~CPM_CPCCR_CDIV_MASK) | (v << (CPM_CPCCR_CDIV_BIT))
|
||||||
static unsigned cpm_set_hdiv (unsigned v):
|
static void cpm_set_hdiv (unsigned v):
|
||||||
return CPM_CPCCR = (CPM_CPCCR & ~CPM_CPCCR_HDIV_MASK) | (v << (CPM_CPCCR_HDIV_BIT))
|
CPM_CPCCR = (CPM_CPCCR & ~CPM_CPCCR_HDIV_MASK) | (v << (CPM_CPCCR_HDIV_BIT))
|
||||||
static unsigned cpm_set_pdiv (unsigned v):
|
static void cpm_set_pdiv (unsigned v):
|
||||||
return CPM_CPCCR = (CPM_CPCCR & ~CPM_CPCCR_PDIV_MASK) | (v << (CPM_CPCCR_PDIV_BIT))
|
CPM_CPCCR = (CPM_CPCCR & ~CPM_CPCCR_PDIV_MASK) | (v << (CPM_CPCCR_PDIV_BIT))
|
||||||
static unsigned cpm_set_mdiv (unsigned v):
|
static void cpm_set_mdiv (unsigned v):
|
||||||
return CPM_CPCCR = (CPM_CPCCR & ~CPM_CPCCR_MDIV_MASK) | (v << (CPM_CPCCR_MDIV_BIT))
|
CPM_CPCCR = (CPM_CPCCR & ~CPM_CPCCR_MDIV_MASK) | (v << (CPM_CPCCR_MDIV_BIT))
|
||||||
static unsigned cpm_set_ldiv (unsigned v):
|
static void cpm_set_ldiv (unsigned v):
|
||||||
return CPM_CPCCR = (CPM_CPCCR & ~CPM_CPCCR_LDIV_MASK) | (v << (CPM_CPCCR_LDIV_BIT))
|
CPM_CPCCR = (CPM_CPCCR & ~CPM_CPCCR_LDIV_MASK) | (v << (CPM_CPCCR_LDIV_BIT))
|
||||||
static unsigned cpm_set_udiv (unsigned v):
|
static void cpm_set_udiv (unsigned v):
|
||||||
return CPM_CPCCR = (CPM_CPCCR & ~CPM_CPCCR_UDIV_MASK) | (v << (CPM_CPCCR_UDIV_BIT))
|
CPM_CPCCR = (CPM_CPCCR & ~CPM_CPCCR_UDIV_MASK) | (v << (CPM_CPCCR_UDIV_BIT))
|
||||||
static unsigned cpm_set_i2sdiv (unsigned v):
|
static void cpm_set_i2sdiv (unsigned v):
|
||||||
return CPM_I2SCDR = (CPM_I2SCDR & ~CPM_I2SCDR_I2SDIV_MASK) | (v << (CPM_I2SCDR_I2SDIV_BIT))
|
CPM_I2SCDR = (CPM_I2SCDR & ~CPM_I2SCDR_I2SDIV_MASK) | (v << (CPM_I2SCDR_I2SDIV_BIT))
|
||||||
static unsigned cpm_set_pixdiv (unsigned v):
|
static void cpm_set_pixdiv (unsigned v):
|
||||||
return CPM_LPCDR = (CPM_LPCDR & ~CPM_LPCDR_PIXDIV_MASK) | (v << (CPM_LPCDR_PIXDIV_BIT))
|
CPM_LPCDR = (CPM_LPCDR & ~CPM_LPCDR_PIXDIV_MASK) | (v << (CPM_LPCDR_PIXDIV_BIT))
|
||||||
static unsigned cpm_set_mscdiv (unsigned v):
|
static void cpm_set_mscdiv (unsigned v):
|
||||||
return CPM_MSCCDR = (CPM_MSCCDR & ~CPM_MSCCDR_MSCDIV_MASK) | (v << (CPM_MSCCDR_MSCDIV_BIT))
|
CPM_MSCCDR = (CPM_MSCCDR & ~CPM_MSCCDR_MSCDIV_MASK) | (v << (CPM_MSCCDR_MSCDIV_BIT))
|
||||||
static unsigned cpm_set_uhcdiv (unsigned v):
|
static void cpm_set_uhcdiv (unsigned v):
|
||||||
return CPM_UHCCDR = (CPM_UHCCDR & ~CPM_UHCCDR_UHCDIV_MASK) | (v << (CPM_UHCCDR_UHCDIV_BIT))
|
CPM_UHCCDR = (CPM_UHCCDR & ~CPM_UHCCDR_UHCDIV_MASK) | (v << (CPM_UHCCDR_UHCDIV_BIT))
|
||||||
static unsigned cpm_ssiclk_select_exclk ():
|
static void cpm_ssiclk_select_exclk ():
|
||||||
return CPM_SSICDR &= ~CPM_SSICDR_SCS
|
CPM_SSICDR &= ~CPM_SSICDR_SCS
|
||||||
static unsigned cpm_ssiclk_select_pllout ():
|
static void cpm_ssiclk_select_pllout ():
|
||||||
return CPM_SSICDR |= CPM_SSICDR_SCS
|
CPM_SSICDR |= CPM_SSICDR_SCS
|
||||||
static unsigned cpm_set_ssidiv (unsigned v):
|
static void cpm_set_ssidiv (unsigned v):
|
||||||
return CPM_SSICDR = (CPM_SSICDR & ~CPM_SSICDR_SSIDIV_MASK) | ((v) << (CPM_SSICDR_SSIDIV_BIT))
|
CPM_SSICDR = (CPM_SSICDR & ~CPM_SSICDR_SSIDIV_MASK) | ((v) << (CPM_SSICDR_SSIDIV_BIT))
|
||||||
|
|
||||||
#define cpm_select_i2sclk_exclk() (CPM_CPCCR &= ~CPM_CPCCR_I2CS)
|
#define cpm_select_i2sclk_exclk() (CPM_CPCCR &= ~CPM_CPCCR_I2CS)
|
||||||
#define cpm_select_i2sclk_pll() (CPM_CPCCR |= CPM_CPCCR_I2CS)
|
#define cpm_select_i2sclk_pll() (CPM_CPCCR |= CPM_CPCCR_I2CS)
|
||||||
@ -2485,7 +2486,7 @@ static unsigned cpm_get_pllout ():
|
|||||||
m = cpm_get_pllm () + 2
|
m = cpm_get_pllm () + 2
|
||||||
n = cpm_get_plln () + 2
|
n = cpm_get_plln () + 2
|
||||||
no = od[cpm_get_pllod ()]
|
no = od[cpm_get_pllod ()]
|
||||||
pllout = ((JZ_EXTAL) / (n * no)) * m
|
pllout = JZ_EXTAL * m / n / no
|
||||||
else:
|
else:
|
||||||
pllout = JZ_EXTAL
|
pllout = JZ_EXTAL
|
||||||
return pllout
|
return pllout
|
||||||
@ -3011,6 +3012,13 @@ static void ac97_cold_reset_codec():
|
|||||||
|
|
||||||
#define i2s_reset_codec() do { } while (0)
|
#define i2s_reset_codec() do { } while (0)
|
||||||
|
|
||||||
|
static void aic_use_internal_codec ():
|
||||||
|
aic_internal_codec ()
|
||||||
|
aic_select_i2s ()
|
||||||
|
i2s_as_slave ()
|
||||||
|
i2s_select_i2s ()
|
||||||
|
cpm_select_i2sclk_exclk ()
|
||||||
|
cpm_set_i2sdiv (1)
|
||||||
|
|
||||||
//**************************************************************************
|
//**************************************************************************
|
||||||
// ICDC
|
// ICDC
|
||||||
@ -3598,8 +3606,8 @@ static void setup_sdram ():
|
|||||||
unsigned cas_latency_dmcr[2] = { 1 << EMC_DMCR_TCL_BIT, 2 << EMC_DMCR_TCL_BIT }
|
unsigned cas_latency_dmcr[2] = { 1 << EMC_DMCR_TCL_BIT, 2 << EMC_DMCR_TCL_BIT }
|
||||||
int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32}
|
int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32}
|
||||||
|
|
||||||
cpu_clk = 225000000
|
cpu_clk = 252000000
|
||||||
gpio_as_sdram_32bit ()
|
gpio_as_sdram_16bit ()
|
||||||
unsigned SDRAM_BW16 = 0
|
unsigned SDRAM_BW16 = 0
|
||||||
unsigned SDRAM_BANK4 = 1
|
unsigned SDRAM_BANK4 = 1
|
||||||
unsigned SDRAM_ROW = 13
|
unsigned SDRAM_ROW = 13
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
// 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__
|
||||||
#include "jz4740.hh"
|
#include "jz4740.hh"
|
||||||
|
|
||||||
asm volatile (".set noreorder\n"
|
asm volatile (".set noreorder\n"
|
||||||
|
@ -21,25 +21,29 @@
|
|||||||
|
|
||||||
.balign 0x1000
|
.balign 0x1000
|
||||||
thread0:
|
thread0:
|
||||||
.incbin "init"
|
.incbin "init.elf"
|
||||||
|
|
||||||
.balign 0x1000
|
.balign 0x1000
|
||||||
thread1:
|
thread1:
|
||||||
.incbin "udc"
|
.incbin "udc.elf"
|
||||||
|
|
||||||
.balign 0x1000
|
.balign 0x1000
|
||||||
thread2:
|
thread2:
|
||||||
.incbin "nanonote-gpio"
|
.incbin "nanonote-gpio.elf"
|
||||||
|
|
||||||
.balign 0x1000
|
.balign 0x1000
|
||||||
thread3:
|
thread3:
|
||||||
.incbin "buzzer"
|
.incbin "buzzer.elf"
|
||||||
|
|
||||||
.balign 0x1000
|
.balign 0x1000
|
||||||
thread4:
|
thread4:
|
||||||
.incbin "metronome"
|
.incbin "metronome.elf"
|
||||||
|
|
||||||
|
.balign 0x1000
|
||||||
thread5:
|
thread5:
|
||||||
|
.incbin "lcd.elf"
|
||||||
|
|
||||||
|
thread6:
|
||||||
|
|
||||||
// Everything from here may be freed after kernel initialization.
|
// Everything from here may be freed after kernel initialization.
|
||||||
init_start:
|
init_start:
|
||||||
@ -51,3 +55,4 @@ thread_start:
|
|||||||
.word thread3
|
.word thread3
|
||||||
.word thread4
|
.word thread4
|
||||||
.word thread5
|
.word thread5
|
||||||
|
.word thread6
|
||||||
|
@ -17,25 +17,25 @@
|
|||||||
|
|
||||||
load = 0x80000000
|
load = 0x80000000
|
||||||
|
|
||||||
ARCH_CXXFLAGS = -DNUM_THREADS=3
|
ARCH_CXXFLAGS = -DNUM_THREADS=3 -DTRENDTAC
|
||||||
ARCH_CPPFLAGS = -Imips -Wa,-mips32
|
ARCH_CPPFLAGS = -I. -Imips -Imips/trendtac -Wa,-mips32
|
||||||
CROSS = mipsel-linux-gnu-
|
CROSS = mipsel-linux-gnu-
|
||||||
OBJDUMP = $(CROSS)objdump
|
OBJDUMP = $(CROSS)objdump
|
||||||
junk = mdebug.abi32 reginfo comment pdr
|
junk = mdebug.abi32 reginfo comment pdr
|
||||||
OBJCOPYFLAGS = $(addprefix --remove-section=.,$(junk))
|
OBJCOPYFLAGS = $(addprefix --remove-section=.,$(junk))
|
||||||
|
|
||||||
arch_iris_sources = mips/interrupts.cc mips/arch.cc
|
arch_iris_sources = mips/interrupts.cc mips/arch.cc
|
||||||
boot_sources = mips/init.cc
|
boot_sources = mips/init.cc mips/trendtac/board.cc
|
||||||
arch_headers = mips/arch.hh mips/jz4730.hh
|
arch_headers = mips/arch.hh mips/trendtac/jz4730.hh mips/trendtac/board.hh
|
||||||
boot_threads = init gpio lcd
|
boot_threads = init gpio lcd
|
||||||
|
|
||||||
uimage:
|
uimage:
|
||||||
|
|
||||||
mips/boot.o: TARGET_FLAGS = -DMEMORY_SIZE = "128 << 20"
|
mips/boot.o: TARGET_FLAGS = -DMEMORY_SIZE="128 << 20"
|
||||||
mips/threadlist.o: $(boot_threads)
|
mips/trendtac/threadlist.o: $(addsuffix .elf,$(boot_threads))
|
||||||
mips/init.o: TARGET_FLAGS = -I/usr/include
|
mips/init.o: TARGET_FLAGS = -I/usr/include
|
||||||
$(boot_threads): TARGET_FLAGS = -I.
|
$(addsuffix .elf,$(boot_threads)): TARGET_FLAGS = -I.
|
||||||
$(addprefix boot-programs/,$(addsuffix .cc,$(boot_threads))): boot-programs/devices.hh boot-programs/init.hh
|
$(addprefix boot-programs/,$(addsuffix .cc,$(boot_threads))): devices.hh
|
||||||
lcd: boot-programs/charset.data
|
lcd: boot-programs/charset.data
|
||||||
|
|
||||||
boot-programs/charset.data: boot-programs/charset
|
boot-programs/charset.data: boot-programs/charset
|
||||||
@ -58,4 +58,4 @@ iris: mips/entry.o $(subst .cc,.o,$(iris_sources)) mips/trendtac/threadlist.o mi
|
|||||||
%.gz: %
|
%.gz: %
|
||||||
gzip < $< > $@
|
gzip < $< > $@
|
||||||
|
|
||||||
ARCH_CLEAN_FILES = uimage $(boot_threads) mips/*.o boot-programs/charset.data iris iris.raw iris.raw.gz
|
ARCH_CLEAN_FILES = uimage $(addsuffix .elf,$(boot_threads)) mips/*.o boot-programs/charset.data iris iris.raw iris.raw.gz
|
||||||
|
@ -16,6 +16,10 @@
|
|||||||
// 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/>.
|
||||||
|
|
||||||
|
#define ARCH
|
||||||
|
#define INIT
|
||||||
|
#include "kernel.hh"
|
||||||
|
|
||||||
void board_init ():
|
void board_init ():
|
||||||
// Disable all gpio interrupts and alternate functions initially.
|
// Disable all gpio interrupts and alternate functions initially.
|
||||||
for unsigned i = 0; i < 4; ++i:
|
for unsigned i = 0; i < 4; ++i:
|
||||||
@ -54,3 +58,12 @@ void board_init ():
|
|||||||
ost_set_count (0, 1)
|
ost_set_count (0, 1)
|
||||||
ost_set_mode (0, OST_TCSR_UIE | OST_TCSR_CKS_EXTAL)
|
ost_set_mode (0, OST_TCSR_UIE | OST_TCSR_CKS_EXTAL)
|
||||||
ost_enable_channel (0)
|
ost_enable_channel (0)
|
||||||
|
|
||||||
|
void arch_reboot ():
|
||||||
|
// Wait for serial port to be done.
|
||||||
|
while !(UART0_LSR & UARTLSR_TEMT):
|
||||||
|
// Reboot.
|
||||||
|
wdt_set_count (~0)
|
||||||
|
wdt_start ()
|
||||||
|
// Wait for wdt to trigger reboot.
|
||||||
|
while true:
|
||||||
|
19
mips/trendtac/board.hhp
Normal file
19
mips/trendtac/board.hhp
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#pypp 0
|
||||||
|
// Iris: micro-kernel for a capability-based operating system.
|
||||||
|
// mips/trendtac/board.hhp: nanonote-specific declarations and type definitions.
|
||||||
|
// Copyright 2009 Bas Wijnen <wijnen@debian.org>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// 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 "jz4730.hh"
|
@ -62,7 +62,7 @@
|
|||||||
#define UPRT_PHYSICAL 0x10061000
|
#define UPRT_PHYSICAL 0x10061000
|
||||||
#define KBC_PHYSICAL 0x10062000
|
#define KBC_PHYSICAL 0x10062000
|
||||||
|
|
||||||
#ifdef __KERNEL
|
#ifdef __KERNEL__
|
||||||
// In kernel space you need to add 0xa0000000 to see them unmapped uncached in kseg2.
|
// In kernel space you need to add 0xa0000000 to see them unmapped uncached in kseg2.
|
||||||
#define HARB_BASE (HARB_PHYSICAL + 0xa0000000)
|
#define HARB_BASE (HARB_PHYSICAL + 0xa0000000)
|
||||||
#define EMC_BASE (EMC_PHYSICAL + 0xa0000000)
|
#define EMC_BASE (EMC_PHYSICAL + 0xa0000000)
|
||||||
@ -2324,7 +2324,7 @@ static __inline__ void udelay (unsigned us):
|
|||||||
for unsigned k = 0; k < 100; ++k:
|
for unsigned k = 0; k < 100; ++k:
|
||||||
GPIO_GPDR (0) = GPIO_GPDR (0)
|
GPIO_GPDR (0) = GPIO_GPDR (0)
|
||||||
|
|
||||||
#ifndef __KERNEL
|
#ifndef __KERNEL__
|
||||||
static __inline__ void cdelay (unsigned ds):
|
static __inline__ void cdelay (unsigned ds):
|
||||||
Kernel::my_receiver.set_alarm (ds * (HZ / 100))
|
Kernel::my_receiver.set_alarm (ds * (HZ / 100))
|
||||||
Kernel::Cap ().call (~0)
|
Kernel::Cap ().call (~0)
|
||||||
@ -3029,7 +3029,7 @@ static __inline__ void gpio_as_cim ():
|
|||||||
#define i2c_read() ( I2C_DR )
|
#define i2c_read() ( I2C_DR )
|
||||||
#define i2c_write(val) ( I2C_DR = (val) )
|
#define i2c_write(val) ( I2C_DR = (val) )
|
||||||
|
|
||||||
#ifndef __KERNEL
|
#ifndef __KERNEL__
|
||||||
static __inline__ void i2c_open ():
|
static __inline__ void i2c_open ():
|
||||||
i2c_set_clk (JZ_EXTAL, 10000)
|
i2c_set_clk (JZ_EXTAL, 10000)
|
||||||
i2c_enable ()
|
i2c_enable ()
|
||||||
|
@ -21,15 +21,15 @@
|
|||||||
|
|
||||||
.balign 0x1000
|
.balign 0x1000
|
||||||
thread0:
|
thread0:
|
||||||
.incbin "init"
|
.incbin "init.elf"
|
||||||
|
|
||||||
.balign 0x1000
|
.balign 0x1000
|
||||||
thread1:
|
thread1:
|
||||||
.incbin "lcd"
|
.incbin "lcd.elf"
|
||||||
|
|
||||||
.balign 0x1000
|
.balign 0x1000
|
||||||
thread2:
|
thread2:
|
||||||
.incbin "gpio"
|
.incbin "gpio.elf"
|
||||||
|
|
||||||
thread3:
|
thread3:
|
||||||
|
|
||||||
|
@ -77,6 +77,13 @@ void panic_impl (unsigned n, unsigned line, char const *name, char const *messag
|
|||||||
dbg_log (message)
|
dbg_log (message)
|
||||||
dbg_log_char ('/')
|
dbg_log_char ('/')
|
||||||
dbg_log_num (n)
|
dbg_log_num (n)
|
||||||
|
dbg_log (" bad vaddr = ")
|
||||||
|
unsigned a
|
||||||
|
cp0_get (CP0_BAD_V_ADDR, a)
|
||||||
|
dbg_log_num (a)
|
||||||
|
dbg_log (" epc = ")
|
||||||
|
cp0_get (CP0_EPC, a)
|
||||||
|
dbg_log_num (a)
|
||||||
dbg_log_char ('\n')
|
dbg_log_char ('\n')
|
||||||
// If no log capability is registered, the machine just hangs.
|
// If no log capability is registered, the machine just hangs.
|
||||||
#ifdef USE_SERIAL
|
#ifdef USE_SERIAL
|
||||||
|
Loading…
Reference in New Issue
Block a user