I noticed a thread on TI-Bank where someone said his TI-Nspire CAS drained a set of batteries by 50% in one day while testing out some programs... Power consumption is a very annoying thing in that you can't ignore it even though it's practically impossible to measure it effectively

I suspect that it's mainly the Nspire's 90MHz CPU that can be a power hog, so it's important to make sure we idle it properly when nothing is happening. The way to do this is with the wait-for-interrupt instruction (mcr p15, 0, SBZ, c7, c0, 4), which is executed by the idle() function in libndls. However, this instruction is only useful if the interrupt that wakes the CPU up is acknowledged. Otherwise, next time around, the interrupt controller is already asserting to the CPU that an interrupt is pending, so the instruction just returns immediately.
Presently, Ndless programs run with the CPSR I bit set on the CPU, so the OS's IRQ handler is not run, and IRQs never get acknowledged unless a program does so explicitly. I think libndls should have a delay routine that keeps the CPU idle by acknowledging timer interrupts as they come, something like this:
1 2 3 4 5 6 7 8 9 10 11 12 13
| // Idle for n/100 seconds void delay(int n) { int irq_mask = *(volatile int *)0xDC000008; *(volatile int *)0xDC00000C = ~(1 << 19); // Disable all IRQs except timer for (; n; n--) { asm ("mcr p15, 0, %0, c7, c0, 4" : : "r" (0)); // Wait for an interrupt to occur *(volatile int *)0x900A0020 = 1; // Acknowledge timer interrupt at source *(volatile int *)0xDC000028; // Make interrupt controller stop asserting nIRQ if there aren't any active IRQs left } *(volatile int *)0xDC000008 = irq_mask; // Re-enable disabled IRQs return 0; }
|