This is an archived, read-only copy of the United-TI subforum , including posts and topic from May 2003 to April 2012. If you would like to discuss any of the topics in this forum, you can visit Cemetech's Technology & Calculator Open Topic subforum. Some of these topics may also be directly-linked to active Cemetech topics. If you are a Cemetech member with a linked United-TI account, you can link United-TI topics here with your current Cemetech topics.

This forum is locked: you cannot post, reply to, or edit topics. Community News & Discuss Nspire => Technology & Calculator Open Topic
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 Very Happy
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 Wink
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

Posted: 19 Jun 2010 05:47:59 pm    Post subject:

maybe this will help: http://hackspire.unsads.com/wiki/index.php/Memory-mapped_I/O_ports#900C0000_-_First_timer
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 Very Happy
i will tell you more if i've done the first page Very Happy
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
Display posts from previous:   
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
    »
» View previous topic :: View next topic  
Page 1 of 1 » All times are UTC - 5 Hours

 

Advertisement