Index: emcore/trunk/init.c |
— | — | @@ -273,5 +273,6 @@ |
274 | 274 | ib->bootalloc = bootalloc;
|
275 | 275 | thread_create(&(ib->initthread), initthreadname, initthread, ib->initstack,
|
276 | 276 | sizeof(ib->initstack), OS_THREAD, 127, true);
|
| 277 | + timer_init();
|
277 | 278 | interrupt_init();
|
278 | 279 | }
|
Index: emcore/trunk/target/ipodnano2g/timer.c |
— | — | @@ -27,22 +27,42 @@ |
28 | 28 | #include "s5l8701.h"
|
29 | 29 |
|
30 | 30 |
|
31 | | -void setup_tick()
|
| 31 | +void timer_init()
|
32 | 32 | {
|
33 | | - int cycles = SYSTEM_TICK / 100;
|
34 | | -
|
35 | | - /* configure timer for 10 kHz */
|
36 | | - TBCMD = (1 << 1); /* TB_CLR */
|
37 | | - TBPRE = 300 - 1; /* prescaler */
|
38 | | - TBCON = (0 << 13) | /* TB_INT1_EN */
|
39 | | - (1 << 12) | /* TB_INT0_EN */
|
| 33 | +}
|
| 34 | +
|
| 35 | +void timer_schedule_wakeup(uint32_t usecs)
|
| 36 | +{
|
| 37 | + if (usecs > 11184640)
|
| 38 | + {
|
| 39 | + TBPRE = 511;
|
| 40 | + TBDATA1 = 65535;
|
| 41 | + }
|
| 42 | + else if (usecs > 21845)
|
| 43 | + {
|
| 44 | + TBPRE = 511;
|
| 45 | + TBDATA1 = (usecs * 192) >> 15;
|
| 46 | + }
|
| 47 | + else
|
| 48 | + {
|
| 49 | + TBPRE = 0;
|
| 50 | + TBDATA1 = (usecs * 192) >> 6;
|
| 51 | + }
|
| 52 | + TBCON = (1 << 13) | /* TB_INT1_EN */
|
| 53 | + (0 << 12) | /* TB_INT0_EN */
|
40 | 54 | (0 << 11) | /* TB_START */
|
41 | 55 | (2 << 8) | /* TB_CS = PCLK / 16 */
|
42 | | - (0 << 4); /* TB_MODE_SEL = interval mode */
|
43 | | - TBDATA0 = cycles; /* set interval period */
|
| 56 | + (2 << 4); /* TB_MODE_SEL = one-shot mode */
|
| 57 | + TBCMD = (1 << 1); /* TB_CLR */
|
44 | 58 | TBCMD = (1 << 0); /* TB_EN */
|
45 | 59 | }
|
46 | 60 |
|
| 61 | +void timer_kill_wakeup()
|
| 62 | +{
|
| 63 | + TBCMD = (1 << 1); /* TB_CLR */
|
| 64 | + TBCON = TBCON;
|
| 65 | +}
|
| 66 | +
|
47 | 67 | void INT_TIMERB(void)
|
48 | 68 | {
|
49 | 69 | TBCON = TBCON;
|
Index: emcore/trunk/target/ipodnano3g/timer.c |
— | — | @@ -27,10 +27,8 @@ |
28 | 28 | #include "s5l8702.h"
|
29 | 29 |
|
30 | 30 |
|
31 | | -void setup_tick()
|
| 31 | +void timer_init()
|
32 | 32 | {
|
33 | | - int cycles = SYSTEM_TICK / 100;
|
34 | | -
|
35 | 33 | TACMD = (1 << 1); /* TA_CLR */
|
36 | 34 | TBCMD = (1 << 1); /* TB_CLR */
|
37 | 35 | TCCMD = (1 << 1); /* TC_CLR */
|
— | — | @@ -37,18 +35,40 @@ |
38 | 36 | TDCMD = (1 << 1); /* TD_CLR */
|
39 | 37 | TGCMD = (1 << 1); /* TG_CLR */
|
40 | 38 | THCMD = (1 << 1); /* TH_CLR */
|
| 39 | +}
|
41 | 40 |
|
42 | | - /* configure timer for 10 kHz */
|
43 | | - TBPRE = 337 - 1; /* prescaler */
|
44 | | - TBCON = (0 << 13) | /* TB_INT1_EN */
|
45 | | - (1 << 12) | /* TB_INT0_EN */
|
| 41 | +void timer_schedule_wakeup(uint32_t usecs)
|
| 42 | +{
|
| 43 | + if (usecs > 9942053)
|
| 44 | + {
|
| 45 | + TBPRE = 511;
|
| 46 | + TBDATA1 = 65535;
|
| 47 | + }
|
| 48 | + else if (usecs > 19417)
|
| 49 | + {
|
| 50 | + TBPRE = 511;
|
| 51 | + TBDATA1 = (usecs * 216) >> 15;
|
| 52 | + }
|
| 53 | + else
|
| 54 | + {
|
| 55 | + TBPRE = 0;
|
| 56 | + TBDATA1 = (usecs * 216) >> 6;
|
| 57 | + }
|
| 58 | + TBCON = (1 << 13) | /* TB_INT1_EN */
|
| 59 | + (0 << 12) | /* TB_INT0_EN */
|
46 | 60 | (0 << 11) | /* TB_START */
|
47 | 61 | (3 << 8) | /* TB_CS = PCLK / 64 */
|
48 | | - (0 << 4); /* TB_MODE_SEL = interval mode */
|
49 | | - TBDATA0 = cycles; /* set interval period */
|
| 62 | + (2 << 4); /* TB_MODE_SEL = one-shot mode */
|
| 63 | + TBCMD = (1 << 1); /* TB_CLR */
|
50 | 64 | TBCMD = (1 << 0); /* TB_EN */
|
51 | 65 | }
|
52 | 66 |
|
| 67 | +void timer_kill_wakeup()
|
| 68 | +{
|
| 69 | + TBCMD = (1 << 1); /* TB_CLR */
|
| 70 | + TBCON = TBCON;
|
| 71 | +}
|
| 72 | +
|
53 | 73 | void INT_TIMERB(void)
|
54 | 74 | {
|
55 | 75 | TBCON = TBCON;
|
Index: emcore/trunk/target/ipodnano4g/timer.c |
— | — | @@ -27,10 +27,8 @@ |
28 | 28 | #include "s5l8720.h"
|
29 | 29 |
|
30 | 30 |
|
31 | | -void setup_tick()
|
| 31 | +void timer_init()
|
32 | 32 | {
|
33 | | - int cycles = SYSTEM_TICK / 100;
|
34 | | -
|
35 | 33 | TACMD = (1 << 1); /* TA_CLR */
|
36 | 34 | TBCMD = (1 << 1); /* TB_CLR */
|
37 | 35 | TCCMD = (1 << 1); /* TC_CLR */
|
— | — | @@ -38,18 +36,40 @@ |
39 | 37 | TFCMD = (1 << 1); /* TF_CLR */
|
40 | 38 | TGCMD = (1 << 1); /* TG_CLR */
|
41 | 39 | THCMD = (1 << 1); /* TH_CLR */
|
| 40 | +}
|
42 | 41 |
|
43 | | - /* configure timer for 10 kHz */
|
44 | | - TBPRE = 208 - 1; /* prescaler */
|
45 | | - TBCON = (0 << 13) | /* TB_INT1_EN */
|
46 | | - (1 << 12) | /* TB_INT0_EN */
|
| 42 | +void timer_schedule_wakeup(uint32_t usecs)
|
| 43 | +{
|
| 44 | + if (usecs > 16146247)
|
| 45 | + {
|
| 46 | + TBPRE = 511;
|
| 47 | + TBDATA1 = 65535;
|
| 48 | + }
|
| 49 | + else if (usecs > 31535)
|
| 50 | + {
|
| 51 | + TBPRE = 511;
|
| 52 | + TBDATA1 = (usecs * 133) >> 15;
|
| 53 | + }
|
| 54 | + else
|
| 55 | + {
|
| 56 | + TBPRE = 0;
|
| 57 | + TBDATA1 = (usecs * 133) >> 6;
|
| 58 | + }
|
| 59 | + TBCON = (1 << 13) | /* TB_INT1_EN */
|
| 60 | + (0 << 12) | /* TB_INT0_EN */
|
47 | 61 | (0 << 11) | /* TB_START */
|
48 | 62 | (3 << 8) | /* TB_CS = PCLK / 64 */
|
49 | | - (0 << 4); /* TB_MODE_SEL = interval mode */
|
50 | | - TBDATA0 = cycles; /* set interval period */
|
| 63 | + (2 << 4); /* TB_MODE_SEL = one-shot mode */
|
| 64 | + TBCMD = (1 << 1); /* TB_CLR */
|
51 | 65 | TBCMD = (1 << 0); /* TB_EN */
|
52 | 66 | }
|
53 | 67 |
|
| 68 | +void timer_kill_wakeup()
|
| 69 | +{
|
| 70 | + TBCMD = (1 << 1); /* TB_CLR */
|
| 71 | + TBCON = TBCON;
|
| 72 | +}
|
| 73 | +
|
54 | 74 | void INT_TIMERB(void)
|
55 | 75 | {
|
56 | 76 | TBCON = TBCON;
|
Index: emcore/trunk/thread.c |
— | — | @@ -238,7 +238,6 @@ |
239 | 239 | idle_thread.type = CORE_THREAD;
|
240 | 240 | idle_thread.name = "idle thread";
|
241 | 241 | idle_thread.stack = (uint32_t*)-1;
|
242 | | - setup_tick();
|
243 | 242 | }
|
244 | 243 |
|
245 | 244 | bool scheduler_freeze(bool value)
|
— | — | @@ -275,6 +274,9 @@ |
276 | 275 | current_thread->block_type = THREAD_DEFUNCT_STKOV;
|
277 | 276 | wakeup_signal(&dbgwakeup);
|
278 | 277 | }
|
| 278 | +
|
| 279 | + timer_kill_wakeup();
|
| 280 | +
|
279 | 281 | if (usec - last_tick > SCHEDULER_TICK)
|
280 | 282 | {
|
281 | 283 | uint32_t diff = usec - last_tick;
|
— | — | @@ -286,10 +288,12 @@ |
287 | 289 | }
|
288 | 290 | }
|
289 | 291 |
|
| 292 | + uint32_t next_unblock = 0xffffffff;
|
290 | 293 | if (scheduler_frozen) thread = &idle_thread;
|
291 | 294 | else
|
292 | 295 | {
|
293 | 296 | for (t = head_thread; t; t = t->thread_next)
|
| 297 | + {
|
294 | 298 | if (t->state == THREAD_BLOCKED && t->timeout != -1
|
295 | 299 | && TIME_AFTER(usec, t->blocked_since + t->timeout))
|
296 | 300 | {
|
— | — | @@ -300,6 +304,12 @@ |
301 | 305 | t->blocked_by = NULL;
|
302 | 306 | t->timeout = 0;
|
303 | 307 | }
|
| 308 | + else if (t->state == THREAD_BLOCKED && t->timeout != -1)
|
| 309 | + {
|
| 310 | + uint32_t left = t->blocked_since + t->timeout - usec;
|
| 311 | + if (left < next_unblock) next_unblock = left;
|
| 312 | + }
|
| 313 | + }
|
304 | 314 |
|
305 | 315 | if (!thread || thread->state != THREAD_READY)
|
306 | 316 | {
|
— | — | @@ -317,6 +327,9 @@ |
318 | 328 | }
|
319 | 329 | }
|
320 | 330 | }
|
| 331 | +
|
| 332 | + if (thread == &idle_thread) timer_schedule_wakeup(next_unblock);
|
| 333 | + else timer_schedule_wakeup(SYSTEM_TICK);
|
321 | 334 | }
|
322 | 335 |
|
323 | 336 | current_thread = thread;
|
Index: emcore/trunk/timer.h |
— | — | @@ -45,7 +45,9 @@ |
46 | 46 | }
|
47 | 47 |
|
48 | 48 |
|
49 | | -void setup_tick() INITCODE_ATTR;
|
| 49 | +void timer_init() INITCODE_ATTR;
|
| 50 | +void timer_schedule_wakeup(uint32_t usecs) ICODE_ATTR;
|
| 51 | +void timer_kill_wakeup() ICODE_ATTR;
|
50 | 52 | void INT_TIMERB() ICODE_ATTR;
|
51 | 53 |
|
52 | 54 |
|