Author |
Message |
|
Lego
Advanced Newbie
Joined: 05 Feb 2010 Posts: 58
|
Posted: 19 Jun 2010 12:00:09 pm Post subject: |
|
|
Hi
i would like to ask if there is something like sleep(ms); timer avaible.
Im going to copy the Still Alive Portal Outro.
I have evertyhting needed done, but now i need a sleep timer that i can get it nearly sync to the Musik
But the Problem is i am not able to write asm, so i need an os call or maybe someone has done such a timer before.
thx |
|
Back to top |
|
|
bwang
Member
Joined: 15 Mar 2009 Posts: 128
|
Posted: 19 Jun 2010 04:06:41 pm Post subject: |
|
|
You can read the clock; but that only works in seconds.
Like so:
Code: int time = * (volatile unsigned*) 0x90090000
How are you printing the text? |
|
Back to top |
|
|
Lego
Advanced Newbie
Joined: 05 Feb 2010 Posts: 58
|
Posted: 19 Jun 2010 04:15:45 pm Post subject: |
|
|
well i'm a noob in c, so my way is very simple, i just made the characters as binary code, change the pixels and move the cursors to the next one
000000000011000001111000110011001100110011001100111111001100110011001100110011000000000000000000 is for example A
then i just set the first 8 pixels in this case white (i just skip them because i wanted transperancy)
then is go to the next line y++ and print the next 8 pixels ...
its inefficient but works
but don't wanted to wait and this was the first way i found.
Is there an way to make sure that it only continues if the previous prints where done?
because without the WAIT("0x1FFFFF", "printchar"); in front of the while:
Code: printchar(" ,:+$+-,/H#MMMMMMM@= =, ",0x0C);
printchar(" =++%%%%+/:-. ",0x0C);
WAIT("0x1FFFFF", "printchar");
lasty=0;
printchar("This was a triumph.",0x00);
time = * (volatile unsigned*) 0x90090000;
temptime = time;
while (time < temptime+1)
{
time = * (volatile unsigned*) 0x90090000;
}
I just Prints 1/2 of the background logo and waits one second (see second screenshot).
But i can't use WAIT more than once, btw this would also be a very ugly way to solve the problem.
Code: extern int lasty;
int printchar(const char* text, int color) {
int i=0;
int p;
int x;
int y;
int lastx=0;
char character;
char *code;
while (text[i] != 0)
{
character=text[i];
if(character == ' ')
{
lastx=8*i;
}
else
{
if(character == '!')
{
code = "000000000011000001111000011110000111100000110000001100000000000000110000001100000000000000000000";
}
else if(character == '\"')
{
code = "000000000110011001100110011001100010010000000000000000000000000000000000000000000000000000000000";
}
...
x=lastx+1;
y=lasty+1;
for (p = 0; p < 96; p++) {
if (code[p] == '1')
{
if ( x < 321 && y < 241)
{
setPixel(x,y,color);
}
else
{
//return 0;
}
}
if ((p+1) % 8 == 0)
{
x=lastx;
y++;
}
x++;
}
}
i++;
lastx=8*i;
}
lasty=12+lasty;
}
Edit: well in seconds its nice but its to rough.
Last edited by Guest on 20 Jun 2010 09:53:25 am; edited 1 time in total |
|
Back to top |
|
|
aktentasche
Newbie
Joined: 11 Jun 2010 Posts: 7
|
|
Back to top |
|
|
Lego
Advanced Newbie
Joined: 05 Feb 2010 Posts: 58
|
Posted: 19 Jun 2010 06:16:13 pm Post subject: |
|
|
aktentasche wrote:
Well yes i've also found this one, but don't know howto use ^^ |
|
Back to top |
|
|
ExtendeD
Advanced Newbie
Joined: 30 Aug 2009 Posts: 91
|
Posted: 20 Jun 2010 03:55:04 am Post subject: |
|
|
Lego wrote:
aktentasche wrote:
Well yes i've also found this one, but don't know howto use ^^
Write to 900C0000 and 900C0004 to configure the frequency of the interrupt.
You then may use the following function to block (and save battery power) until the interrupt triggers.
Code: /* switch to low-power state until next interrupt */
static inline void idle(void) {
unsigned int sbz = 0;
asm volatile ("mcr p15, 0, %0, c7, c0, 4" : "=r"(sbz) );
}
I suppose you also need to read 900C0000 after the call to check if the timer has reached 0, because idle() may return because of another interrupt.
This is completely untested, please share anything you find out.
calc84maniac may also have more info on this. |
|
Back to top |
|
|
Lego
Advanced Newbie
Joined: 05 Feb 2010 Posts: 58
|
Posted: 20 Jun 2010 10:53:51 am Post subject: |
|
|
what is the size of 900C0000?
I wanted to set it with memset but don't know the size.
And you meant to use it like this?
Code: int sleep(int ms) {
int time = * (volatile unsigned*) 0x900C0000;
memset(ADDR_(0x900C0004), 32, timersize);
memset(ADDR_(0x900C0000), ms, timersize);
idle();
if (time > 0) {
idle();
}
}
maybe with an other ticks count, i need to test it if i would know the size.
Last edited by Guest on 20 Jun 2010 11:06:02 am; edited 1 time in total |
|
Back to top |
|
|
bwang
Member
Joined: 15 Mar 2009 Posts: 128
|
Posted: 20 Jun 2010 04:33:53 pm Post subject: |
|
|
You don't use memset; you write to it like so
Code:
*(volatile unsigned*) 0x900C0000 = <value>
|
|
Back to top |
|
|
Lego
Advanced Newbie
Joined: 05 Feb 2010 Posts: 58
|
Posted: 21 Jun 2010 12:33:30 pm Post subject: |
|
|
bwang wrote:
You don't use memset; you write to it like so
Code:
*(volatile unsigned*) 0x900C0000 = <value>
Well yes is works, but i can't try it exaclty because i still have the problem that it starts the function and continues without checking if the function was done.
So i would need several of this function: WAIT("0x1FFFFF", "printchar"); |
|
Back to top |
|
|
aktentasche
Newbie
Joined: 11 Jun 2010 Posts: 7
|
Posted: 21 Jun 2010 05:49:55 pm Post subject: |
|
|
maybe u should read something about interrupts and using timers.. trial and error is not the best to learn low-level hardware c-progamming ;)
im not into programming the nspire (i will be), maybe this example for a 8051 microcontroller will help:
1.) u inititialize the timer with a value, lets say 1000
2.) u start the timer and enable the timerinterrupt
3.) the timer starts to count up to 0xFF hex or 65535 decimal
4.) then the interrupt will be activated. this means: ur normal code execution is interrupted and the program continues at a certain address (interrupt vector)
5.) the code at this address will be executed
6.) after that, ur normal code execution will continue until the next timer interrupt occurs (until it counts again to 0xFF)
each timerstep needs a certain amount of time, e.g. 1µs
i think the nspire timer works like this: the timer decrements an amount of ticks, e.g. 32. a tick is a multiple of 1/32kHz = 1/32ms = 31,25µs.
all in all i count like this: timervalue(900C0000)*tickvalue(90C0004)*31,25µs. both values should be 4 bytes long, so it can hold up a value up to 2^32 (8*8*8*8 )
Last edited by Guest on 21 Jun 2010 05:52:56 pm; edited 1 time in total |
|
Back to top |
|
|
Lego
Advanced Newbie
Joined: 05 Feb 2010 Posts: 58
|
Posted: 22 Jun 2010 08:11:00 am Post subject: |
|
|
Well my problem is not to get the timer working...
my problem is that the code runs async...
it starts the functions without waiting that they are finished, so the arm is sent sleeping while the print wasn't finished...
i've never coded in c before, but in my other languages this never happend, so i don't know thats the problem^^
Last edited by Guest on 22 Jun 2010 08:31:26 am; edited 1 time in total |
|
Back to top |
|
|
bwang
Member
Joined: 15 Mar 2009 Posts: 128
|
Posted: 22 Jun 2010 05:10:52 pm Post subject: |
|
|
Can you post the code?
It could be the compiler optimizing your code in a way that breaks it. |
|
Back to top |
|
|
Lego
Advanced Newbie
Joined: 05 Feb 2010 Posts: 58
|
Posted: 23 Jun 2010 10:08:42 am Post subject: |
|
|
Well i got it work
i will tell you more if i've done the first page
Well i'm going to bed now, but i just want to show you the first page of the outro^^
i just testet it yet on the emulator, so the timing could have some problem on the real calc.
(Just rename the portal.7z.txt to portal.7z)
Edit: Now i made it, its nearly perfect :D
Capture without Music see Attachments
with Musik: http://www.youtube.com/watch?v=4TbWK_WIbGQ
Last edited by Guest on 20 Jul 2010 08:03:53 pm; edited 1 time in total |
|
Back to top |
|
|
Levak
Advanced Newbie
Joined: 11 Nov 2009 Posts: 94
|
Posted: 28 Sep 2010 02:31:09 pm Post subject: |
|
|
Hi,
Even if I totally understand your sleep function, even if I tried to make one by myself with this and it failed, even all those events, I can't manage to get it working with timer1 0x900C0000 altough I can with timer2 0x900D0000...but comes in conflict with the Nspire internal clock (I get some freezes when I exit the program even if I restore the timer default value).
Does anyone got an idea ?
If you can see where is the problem, here is the "simple" code I made to test Lego's sleeptimer function :
---- main.c ------
Code: #include "keys.h"
#include "draw.h"
#include "functions.h"
asm(".string \"PRG\"");
//asm("ldr sp,=0x12000000"); // pour l'émulateur
int main(void) {
clrscr();
while(!isKeyEscPressed()){
if (isKeyEnterPressed()){
rect_fill(150, 110, 170, 130, 0);
sleep(1000);
clrscr();
}
}
return 0;
}
---- function.c ----
Code: static inline void idle(void) {
unsigned int sbz = 0;
asm volatile ("mcr p15, 0, %0, c7, c0, 4" : "=r"(sbz) );
}
int sleep(int ms) {
*(volatile unsigned*) 0x900C0004 = 22;
*(volatile unsigned*) 0x900C0000 = ms;
while (*(volatile unsigned*) 0x900C0000 > 0)
idle();
}
The problem is : The timer is infinitly fast. The Rectangle fills and disapears as fast. |
|
Back to top |
|
|
Lego
Advanced Newbie
Joined: 05 Feb 2010 Posts: 58
|
Posted: 29 Sep 2010 10:25:34 am Post subject: |
|
|
Levak wrote:
The problem is : The timer is infinitly fast. The Rectangle fills and disapears as fast.
If i remember my Problems correctly, i had the Problem that i need WAIT if i use the sleep code in the main.c
Don't know why, but if you use the main.c with sleep it takes some ms before it idles the cpu and just continues. (Same was with my second picture, there i started the sleep but it just continued printing until the cpu was sent to idle)
This Error did not happen if i put the code which starts the sleep function, in my case StillAlive(), in the same file as the sleep function is.
Thats why the most of my code is placed there. Don't know how to solve this Problem, exept placing everything in this file (functions.c) and start it with
Code: if (isKeyEnterPressed()){
code();
}
Code: inline void code() {
rect_fill(150, 110, 170, 130, 0);
sleep(1000);
clrscr();
}
The second Problem was that i calculated that 0x900C0004 should be 30-32 or so, i can't remember. But if i used these counts the time was far away from one ms, so i tryed to find a good count with try and error to get 0x900C0000 10000 fits 10 seconds.
Last edited by Guest on 29 Sep 2010 10:32:57 am; edited 1 time in total |
|
Back to top |
|
|
calc84maniac
Elite
Joined: 22 Jan 2007 Posts: 770
|
Posted: 30 Sep 2010 09:34:21 am Post subject: |
|
|
Actually, it seems that writes to the First Timer are disabled by the Nspire OS (it's used in TI-84+ mode though). After a search through some IRC logs, I found that you have to reset bit 0x800 of port 0x900B0018 to enable writes to the First Timer. I really should start documenting this stuff on hackspire. |
|
Back to top |
|
|
ExtendeD
Advanced Newbie
Joined: 30 Aug 2009 Posts: 91
|
Posted: 01 Oct 2010 01:18:25 pm Post subject: |
|
|
Lego, Levak, did you try to fix common.h by adding the volatile keyword to isKeyPressed? This will be fixed in Ndless 1.7.
Code: #define isKeyPressed(key) (!((*(volatile short*)(KEY_MAP + (key).row)) & (key).col))
Lego wrote:
The second Problem was that i calculated that 0x900C0004 should be 30-32 or so, i can't remember.
It should be 31. |
|
Back to top |
|
|
|