# HG changeset patch # User Paul Boddie # Date 1463258826 -7200 # Node ID 5dc17c3c1773dcf73bf428e63dd84e8267e07102 # Parent aa19895c149a10fc174d565e3cabffd1d1260fe3 Let the power button switch between tasks, using an IRQ that occurs when the power button signal is low (edge-triggered IRQs do not seem to work). Introduced a general IRQ-clearing function. diff -r aa19895c149a -r 5dc17c3c1773 include/mips.h --- a/include/mips.h Sat May 14 21:40:59 2016 +0200 +++ b/include/mips.h Sat May 14 22:47:06 2016 +0200 @@ -16,6 +16,7 @@ #define CP0_TAGLO $28 #define CP0_TAGHI $29 +#define STATUS_CP0 0x10000000 #define STATUS_BEV 0x00400000 #define STATUS_IRQ 0x0000fc00 #define STATUS_UM 0x00000010 diff -r aa19895c149a -r 5dc17c3c1773 include/nanonote.h --- a/include/nanonote.h Sat May 14 21:40:59 2016 +0200 +++ b/include/nanonote.h Sat May 14 22:47:06 2016 +0200 @@ -53,4 +53,6 @@ #define SPDA (2 * 32 + 22) /* LCDSCL:Serial command clock input */ #define SPCK (2 * 32 + 23) /* LCDSDA:Serial command data input */ +#define GPIO_IRQ IRQ_GPIO3 + #endif /* __NANONOTE_H__ */ diff -r aa19895c149a -r 5dc17c3c1773 stage2/board-nanonote.c --- a/stage2/board-nanonote.c Sat May 14 21:40:59 2016 +0200 +++ b/stage2/board-nanonote.c Sat May 14 22:47:06 2016 +0200 @@ -153,6 +153,45 @@ __tcu_clear_full_match_flag(TIMER_CHAN); } +/* GPIO interrupt activation. */ + +void gpio_init_irq() +{ +/* + unsigned int i; + for (i = 0; i < 7; i++) { + __gpio_as_irq_rise_edge(GPIO_KEYIN_BASE + i); + } +*/ + __gpio_as_irq_low_level(GPIO_POWER); + __intc_unmask_irq(GPIO_IRQ); +} + +int gpio_have_irq(u8 gpio) +{ + return (REG_GPIO_PXFLG(gpio / 32) & (1 << (gpio % 32))); +} + +void gpio_clear(u8 gpio) +{ + /* Clear interrupt status. */ + + __gpio_ack_irq(gpio); + __intc_ack_irq(GPIO_IRQ); +} + +/* Miscellaneous interrupt administration. */ + +void irq_clear() +{ + u8 i; + + for (i = 0; i < 32; i++) { + if (REG_INTC_IPR & (1 << i)) + __intc_ack_irq(i); + } +} + /* Board startup detection. */ int is_started() diff -r aa19895c149a -r 5dc17c3c1773 stage2/cpu_op.S --- a/stage2/cpu_op.S Sat May 14 21:40:59 2016 +0200 +++ b/stage2/cpu_op.S Sat May 14 22:47:06 2016 +0200 @@ -131,6 +131,8 @@ enter_task: mfc0 $t3, CP0_STATUS ori $t3, $t3, STATUS_EXL | STATUS_UM + /* li $t4, STATUS_CP0 ** flag resides in the upper 16 bits, needed... */ + /* or $t3, $t3, $t4 ** for debugging by accessing CP0 in user mode */ mtc0 $t3, CP0_STATUS eret nop diff -r aa19895c149a -r 5dc17c3c1773 stage2/init.h --- a/stage2/init.h Sat May 14 21:40:59 2016 +0200 +++ b/stage2/init.h Sat May 14 22:47:06 2016 +0200 @@ -1,14 +1,31 @@ #ifndef __INIT_H__ #define __INIT_H__ +#include "xburst_types.h" + /* Initialisation functions. */ void gpio_init2(); void cpm_init(); void rtc_init(); + +/* Timer. */ + void timer_init(); void timer_init_irq(); void timer_clear(); + +/* GPIO. */ + +void gpio_init_irq(); +int gpio_have_irq(u8); +void gpio_clear(u8); + +/* General. */ +void irq_clear(); + +/* Test for initialisation. */ + int is_started(); #endif /* __INIT_H__ */ diff -r aa19895c149a -r 5dc17c3c1773 stage2/irq.c --- a/stage2/irq.c Sat May 14 21:40:59 2016 +0200 +++ b/stage2/irq.c Sat May 14 22:47:06 2016 +0200 @@ -32,31 +32,40 @@ { handle_error_level(); timer_init_irq(); + gpio_init_irq(); init_interrupts(); } void irq_handle() { - unsigned short i; - /* Check interrupt identity. */ if (REG_INTC_IPR & (1 << TIMER_CHAN_IRQ)) { - /* Switch task. */ - - switch_task(); - /* Clear interrupt status. */ timer_clear(); + } + + /* GPIO interrupts. */ + + if (REG_INTC_IPR & (1 << GPIO_IRQ)) { + + /* Check for the power button. */ + + if (gpio_have_irq(GPIO_POWER)) { + + /* Switch task. */ + + switch_task(); + + /* Clear interrupt status. */ + + gpio_clear(GPIO_POWER); + } + } /* Handle other interrupts, anyway. */ - } else { - for (i = 0; i < 32; i++) { - if (REG_INTC_IPR & (1 << i)) - __intc_ack_irq(i); - } - } + irq_clear(); }