aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitri Sokolyuk <demon@dim13.org>2011-11-02 02:54:40 +0000
committerDimitri Sokolyuk <demon@dim13.org>2011-11-02 02:54:40 +0000
commit87dd379c89dbe9b63dd3ab0f20f002a20d789c47 (patch)
treeafc0c66c7641377fd5228fd5a6aee5b35dc99a24
parente754d6f8f1288fa3ae5032ef675f35268a484c79 (diff)
major update: lot of bugfixes, lot of changes
- let compiler handle stack pointer arithmetic: switch to 16bit - improve update(): deadline depends on incremental release - resolve timing issues, new time convertion macros - major simplification of scheduler, most of garbage removed - new overflow interrupt for cycle counter, resolves also timing problems - simplify pwm generation, lookup tables are deferred, switch to 4bit - add blocking on shared values - remove garbage in lcd module and some bugfixes - add alternative reboot command to uart command interpreter - KISS
-rw-r--r--kernel/clock.c33
-rw-r--r--kernel/color.h90
-rw-r--r--kernel/ctrl.c6
-rw-r--r--kernel/dmx.c30
-rw-r--r--kernel/dmx/Makefile10
-rw-r--r--kernel/factor.h35
-rw-r--r--kernel/factor10000.h35
-rw-r--r--kernel/heartbeat.c14
-rw-r--r--kernel/kernel.c190
-rw-r--r--kernel/kernel.h65
-rw-r--r--kernel/lcd3.c90
-rw-r--r--kernel/rgb.c188
-rw-r--r--kernel/stack.h3
-rw-r--r--kernel/tasks.h16
-rw-r--r--kernel/uart.c1
15 files changed, 400 insertions, 406 deletions
diff --git a/kernel/clock.c b/kernel/clock.c
index c098481..790391e 100644
--- a/kernel/clock.c
+++ b/kernel/clock.c
@@ -17,6 +17,7 @@
#include <inttypes.h>
#include <avr/io.h>
+#include <stdio.h>
#include <stdlib.h>
#include "kernel.h"
#include "tasks.h"
@@ -24,27 +25,31 @@
void
clock(void *arg)
{
- struct clockarg *a = arg;
+ struct lcdarg *a = arg;
+ uint8_t d, h, m, s;
- a->s = a->m = a->h = a->d = 0;
+ d = h = m = s = 0;
- update(0, SEC(1));
+ update(0, SEC(500));
for (;;) {
- a->s += 1;
- if (a->s == 60) {
- a->s = 0;
- a->m += 1;
+ s += 1;
+ if (s == 60) {
+ s = 0;
+ m += 1;
}
- if (a->m == 60) {
- a->m = 0;
- a->h += 1;
+ if (m == 60) {
+ m = 0;
+ h += 1;
}
- if (a->h == 24) {
- a->h = 0;
- a->d += 1;
+ if (h == 24) {
+ h = 0;
+ d += 1;
}
- sleep(HARD, SEC(1));
+ sprintf(a->first, "%8lx", now());
+ sprintf(a->second, "%4d:%.2d:%.2d:%.2d", d, h, m, s);
+
+ update(SEC(1), MSEC(500));
}
}
diff --git a/kernel/color.h b/kernel/color.h
new file mode 100644
index 0000000..b208377
--- /dev/null
+++ b/kernel/color.h
@@ -0,0 +1,90 @@
+#ifndef __COLOR_H
+#define __COLOR_H
+
+struct color {
+ uint8_t color, r, g, b;
+} color[] PROGMEM = {
+ { 10, 0xff, 0x38, 0x00 },
+ { 11, 0xff, 0x47, 0x00 },
+ { 12, 0xff, 0x53, 0x00 },
+ { 13, 0xff, 0x5d, 0x00 },
+ { 14, 0xff, 0x65, 0x00 },
+ { 15, 0xff, 0x6d, 0x00 },
+ { 16, 0xff, 0x73, 0x00 },
+ { 17, 0xff, 0x79, 0x00 },
+ { 18, 0xff, 0x7e, 0x00 },
+ { 19, 0xff, 0x83, 0x00 },
+ { 20, 0xff, 0x89, 0x12 },
+ { 21, 0xff, 0x8e, 0x21 },
+ { 22, 0xff, 0x93, 0x2c },
+ { 23, 0xff, 0x98, 0x36 },
+ { 24, 0xff, 0x9d, 0x3f },
+ { 25, 0xff, 0xa1, 0x48 },
+ { 26, 0xff, 0xa5, 0x4f },
+ { 27, 0xff, 0xa9, 0x57 },
+ { 28, 0xff, 0xad, 0x5e },
+ { 29, 0xff, 0xb1, 0x65 },
+ { 30, 0xff, 0xb4, 0x6b },
+ { 31, 0xff, 0xb8, 0x72 },
+ { 32, 0xff, 0xbb, 0x78 },
+ { 33, 0xff, 0xbe, 0x7e },
+ { 34, 0xff, 0xc1, 0x84 },
+ { 35, 0xff, 0xc4, 0x89 },
+ { 36, 0xff, 0xc7, 0x8f },
+ { 37, 0xff, 0xc9, 0x94 },
+ { 38, 0xff, 0xcc, 0x99 },
+ { 39, 0xff, 0xce, 0x9f },
+ { 40, 0xff, 0xd1, 0xa3 },
+ { 41, 0xff, 0xd3, 0xa8 },
+ { 42, 0xff, 0xd5, 0xad },
+ { 43, 0xff, 0xd7, 0xb1 },
+ { 44, 0xff, 0xd9, 0xb6 },
+ { 45, 0xff, 0xdb, 0xba },
+ { 46, 0xff, 0xdd, 0xbe },
+ { 47, 0xff, 0xdf, 0xc2 },
+ { 48, 0xff, 0xe1, 0xc6 },
+ { 49, 0xff, 0xe3, 0xca },
+ { 50, 0xff, 0xe4, 0xce },
+ { 51, 0xff, 0xe6, 0xd2 },
+ { 52, 0xff, 0xe8, 0xd5 },
+ { 53, 0xff, 0xe9, 0xd9 },
+ { 54, 0xff, 0xeb, 0xdc },
+ { 55, 0xff, 0xec, 0xe0 },
+ { 56, 0xff, 0xee, 0xe3 },
+ { 57, 0xff, 0xef, 0xe6 },
+ { 58, 0xff, 0xf0, 0xe9 },
+ { 59, 0xff, 0xf2, 0xec },
+ { 60, 0xff, 0xf3, 0xef },
+ { 61, 0xff, 0xf4, 0xf2 },
+ { 62, 0xff, 0xf5, 0xf5 },
+ { 63, 0xff, 0xf6, 0xf8 },
+ { 64, 0xff, 0xf8, 0xfb },
+ { 65, 0xff, 0xf9, 0xfd },
+ { 66, 0xfe, 0xf9, 0xff },
+ { 67, 0xfc, 0xf7, 0xff },
+ { 68, 0xf9, 0xf6, 0xff },
+ { 69, 0xf7, 0xf5, 0xff },
+ { 70, 0xf5, 0xf3, 0xff },
+ { 71, 0xf3, 0xf2, 0xff },
+ { 72, 0xf0, 0xf1, 0xff },
+ { 73, 0xef, 0xf0, 0xff },
+ { 74, 0xed, 0xef, 0xff },
+ { 75, 0xeb, 0xee, 0xff },
+ { 76, 0xe9, 0xed, 0xff },
+ { 77, 0xe7, 0xec, 0xff },
+ { 78, 0xe6, 0xeb, 0xff },
+ { 79, 0xe4, 0xea, 0xff },
+ { 80, 0xe3, 0xe9, 0xff },
+ { 81, 0xe1, 0xe8, 0xff },
+ { 82, 0xe0, 0xe7, 0xff },
+ { 83, 0xde, 0xe6, 0xff },
+ { 84, 0xdd, 0xe6, 0xff },
+ { 85, 0xdc, 0xe5, 0xff },
+ { 86, 0xda, 0xe4, 0xff },
+ { 87, 0xd9, 0xe3, 0xff },
+ { 88, 0xd8, 0xe3, 0xff },
+ { 89, 0xd7, 0xe2, 0xff },
+ { 90, 0xd6, 0xe1, 0xff },
+};
+
+#endif
diff --git a/kernel/ctrl.c b/kernel/ctrl.c
index 3becb49..720002e 100644
--- a/kernel/ctrl.c
+++ b/kernel/ctrl.c
@@ -26,15 +26,15 @@ ctrl(void *arg)
{
struct ctrlarg *a = arg;
- update(0, MSEC(500));
+ update(now(), MSEC(500));
for (;;) {
- sprintf(a->lcd->first, "the time is now:");
+ sprintf(a->lcd->first, "%8lx", now());
sprintf(a->lcd->second, "%4d:%.2d:%.2d:%.2d",
a->clock->d,
a->clock->h,
a->clock->m,
a->clock->s);
- sleep(SOFT, MSEC(500));
+ update(MSEC(500), MSEC(750));
}
}
diff --git a/kernel/dmx.c b/kernel/dmx.c
index 504ffaf..4b30f1e 100644
--- a/kernel/dmx.c
+++ b/kernel/dmx.c
@@ -20,17 +20,15 @@
#include "kernel.h"
#include "tasks.h"
-/* globals */
-uint8_t red, green, blue;
-struct rgbarg rgbargs = { &red, &green, &blue };
+struct rgbarg rgbargs;
+
struct pwmarg pwmargs[] = {
- { &red, PB2 },
- { &green, PB3 },
- { &blue, PB4 }
+ { &rgbargs.r, PB2, &rgbargs.m },
+ { &rgbargs.g, PB3, &rgbargs.m },
+ { &rgbargs.b, PB4, &rgbargs.m }
};
+
struct lcdarg lcdarg;
-struct clockarg clockarg;
-struct ctrlarg ctrlarg = { &lcdarg, &clockarg };
int
main()
@@ -38,26 +36,26 @@ main()
init(STACK);
init_uart();
- semaphore(0, 1);
-
- exec(heartbeat, STACK, 0); // 48
+#if 1
+ exec(heartbeat, STACK, 0); /* stack 48 */
+#endif
#if 1
exec(rgb, STACK + 16, &rgbargs);
exec(pwm, STACK, &pwmargs[0]);
exec(pwm, STACK, &pwmargs[1]);
exec(pwm, STACK, &pwmargs[2]);
+#endif
+
#if 0
exec(cmd, STACK, &rgbargs);
#endif
+
#if 1
exec(lcd, STACK, &lcdarg);
- exec(clock, STACK, &clockarg);
- exec(ctrl, STACK + 8, &ctrlarg);
+ exec(clock, STACK, &lcdarg);
#endif
-#endif
-
- for (;;); /* idle task */
+ idle();
return 0;
}
diff --git a/kernel/dmx/Makefile b/kernel/dmx/Makefile
index 051b5b2..72cbd27 100644
--- a/kernel/dmx/Makefile
+++ b/kernel/dmx/Makefile
@@ -2,15 +2,19 @@
MCU= atmega8
F_CPU= 16000000
-PRESCALE= 8
+#F_CPU= 14745600
+#PRESCALE= 1 # res 62.5nsec cycle 4msec
+PRESCALE= 8 # res 0.5usec cycle 32.7msec
+#PRESCALE= 64 # res 4usec cycle 262msec
+#PRESCALE= 256 # res 16msec cycle 1 sec
+#PRESCALE= 1024 # res 64msec cycle 4 sec
STACK= 48
TASKS= 8
SEMAPHORES= 8
BAUD= 9600
PROG= dmx
-SRCS= dmx.c heartbeat.c rgb.c hsv.c \
- clock.c lcd3.c ctrl.c uart.c
+SRCS= dmx.c heartbeat.c rgb.c hsv.c clock.c lcd3.c uart.c
NOMAN=
.include <bsd.prog.mk>
diff --git a/kernel/factor.h b/kernel/factor.h
new file mode 100644
index 0000000..a3b118b
--- /dev/null
+++ b/kernel/factor.h
@@ -0,0 +1,35 @@
+/* 1/sqrt(2) timing scala in usec */
+uint16_t factor[256] PROGMEM = {
+ 30, 30, 31, 31, 32, 32, 33, 34,
+ 34, 35, 35, 36, 37, 37, 38, 39,
+ 39, 40, 41, 41, 42, 43, 44, 44,
+ 45, 46, 47, 48, 48, 49, 50, 51,
+ 52, 53, 54, 55, 56, 57, 58, 59,
+ 60, 61, 62, 63, 64, 65, 66, 68,
+ 69, 70, 71, 72, 74, 75, 76, 78,
+ 79, 80, 82, 83, 85, 86, 88, 89,
+ 91, 92, 94, 96, 97, 99, 101, 103,
+ 104, 106, 108, 110, 112, 114, 116, 118,
+ 120, 122, 124, 126, 129, 131, 133, 136,
+ 138, 140, 143, 145, 148, 150, 153, 156,
+ 158, 161, 164, 167, 170, 173, 176, 179,
+ 182, 185, 189, 192, 195, 199, 202, 206,
+ 209, 213, 217, 220, 224, 228, 232, 236,
+ 240, 245, 249, 253, 258, 262, 267, 272,
+ 276, 281, 286, 291, 296, 301, 307, 312,
+ 317, 323, 329, 334, 340, 346, 352, 358,
+ 365, 371, 378, 384, 391, 398, 405, 412,
+ 419, 426, 434, 441, 449, 457, 465, 473,
+ 481, 490, 498, 507, 516, 525, 534, 544,
+ 553, 563, 573, 583, 593, 603, 614, 625,
+ 635, 647, 658, 669, 681, 693, 705, 717,
+ 730, 743, 756, 769, 782, 796, 810, 824,
+ 839, 853, 868, 883, 899, 915, 931, 947,
+ 963, 980, 997, 1015, 1033, 1051, 1069, 1088,
+ 1107, 1126, 1146, 1166, 1186, 1207, 1228, 1250,
+ 1271, 1294, 1316, 1339, 1363, 1386, 1411, 1435,
+ 1460, 1486, 1512, 1538, 1565, 1593, 1621, 1649,
+ 1678, 1707, 1737, 1767, 1798, 1830, 1862, 1894,
+ 1927, 1961, 1995, 2030, 2066, 2102, 2138, 2176,
+ 2214, 2253, 2292, 2332, 2373, 2414, 2457, 2500,
+};
diff --git a/kernel/factor10000.h b/kernel/factor10000.h
new file mode 100644
index 0000000..2985026
--- /dev/null
+++ b/kernel/factor10000.h
@@ -0,0 +1,35 @@
+#ifndef __FACTOR_H
+#define __FACTOR_H
+
+/* octave: round(sqrt(2).^(0:(1/16):16) * 10000 / 256)(2:end) */
+
+uint16_t factor[256] PROGMEM = {
+ 40, 41, 42, 43, 44, 44, 45, 46, 47, 49,
+ 50, 51, 52, 53, 54, 55, 56, 58, 59, 60,
+ 62, 63, 64, 66, 67, 69, 70, 72, 73, 75,
+ 76, 78, 80, 82, 83, 85, 87, 89, 91, 93,
+ 95, 97, 99, 101, 104, 106, 108, 110, 113, 115,
+ 118, 120, 123, 126, 129, 131, 134, 137, 140, 143,
+ 146, 150, 153, 156, 160, 163, 167, 170, 174, 178,
+ 182, 186, 190, 194, 198, 203, 207, 212, 216, 221,
+ 226, 231, 236, 241, 246, 252, 257, 263, 269, 274,
+ 280, 287, 293, 299, 306, 313, 319, 326, 333, 341,
+ 348, 356, 364, 372, 380, 388, 397, 405, 414, 423,
+ 432, 442, 452, 462, 472, 482, 492, 503, 514, 526,
+ 537, 549, 561, 573, 586, 599, 612, 625, 639, 653,
+ 667, 682, 696, 712, 727, 743, 760, 776, 793, 811,
+ 828, 846, 865, 884, 903, 923, 943, 964, 985, 1007,
+ 1029, 1051, 1074, 1098, 1122, 1146, 1171, 1197, 1223, 1250,
+ 1277, 1305, 1334, 1363, 1393, 1423, 1455, 1487, 1519, 1552,
+ 1586, 1621, 1657, 1693, 1730, 1768, 1806, 1846, 1886, 1928,
+ 1970, 2013, 2057, 2102, 2148, 2195, 2243, 2293, 2343, 2394,
+ 2446, 2500, 2555, 2611, 2668, 2726, 2786, 2847, 2909, 2973,
+ 3038, 3105, 3173, 3242, 3313, 3386, 3460, 3536, 3613, 3692,
+ 3773, 3856, 3940, 4026, 4114, 4204, 4297, 4391, 4487, 4585,
+ 4685, 4788, 4893, 5000, 5109, 5221, 5336, 5453, 5572, 5694,
+ 5819, 5946, 6076, 6209, 6345, 6484, 6626, 6771, 6920, 7071,
+ 7226, 7384, 7546, 7711, 7880, 8052, 8229, 8409, 8593, 8781,
+ 8974, 9170, 9371, 9576, 9786, 10000
+};
+
+#endif
diff --git a/kernel/heartbeat.c b/kernel/heartbeat.c
index b562d26..7ae97ae 100644
--- a/kernel/heartbeat.c
+++ b/kernel/heartbeat.c
@@ -20,7 +20,7 @@
#include "kernel.h"
#include "tasks.h"
-#define PIN PB0
+#define PIN PB0
void
heartbeat(void *arg)
@@ -30,19 +30,21 @@ heartbeat(void *arg)
DDRB |= _BV(PIN);
PORTB &= ~_BV(PIN);
- update(0, MSEC(750));
+#define DL MSEC(5)
+
+ update(now(), DL);
for (;;) {
PORTB |= _BV(PIN);
- sleep(SOFT, MSEC(100));
+ update(MSEC(100), DL);
PORTB &= ~_BV(PIN);
- sleep(SOFT, MSEC(50));
+ update(MSEC(50), DL);
PORTB |= _BV(PIN);
- sleep(SOFT, MSEC(100));
+ update(MSEC(100), DL);
PORTB &= ~_BV(PIN);
- sleep(SOFT, MSEC(500));
+ update(MSEC(500), DL);
}
}
diff --git a/kernel/kernel.c b/kernel/kernel.c
index 5060687..bf8fee9 100644
--- a/kernel/kernel.c
+++ b/kernel/kernel.c
@@ -25,22 +25,20 @@
#include "kernel.h"
#include "stack.h"
-enum { TERMINATED, RUNQ, TIMEQ, WAITQOFFSET };
+enum State { TERMINATED, RUNQ, TIMEQ, WAITQOFFSET };
#define LO8(x) ((uint8_t)((uint16_t)(x)))
#define HI8(x) ((uint8_t)((uint16_t)(x) >> 8))
#define SCHEDULE TIMER1_COMPA_vect
#define DISTANCE(from, to) ((int32_t)((to) - (from)))
-#define EPOCH 0x3FFFFFFFUL /* XXX */
-#define EPS (LATENCY / PRESCALE + 1) /* XXX */
+#define EPOCH (INT32_MAX >> 1)
#define NOW(hi, lo) (((uint32_t)(hi) << 0x10) | (lo))
struct task {
- uint8_t spl;
- uint8_t sph;
+ uint8_t state;
+ uint16_t sp; /* stack pointer */
uint32_t release;
uint32_t deadline;
- uint8_t state;
};
struct kernel {
@@ -52,28 +50,24 @@ struct kernel {
uint16_t cycles;
} kernel;
-ISR(SCHEDULE, ISR_NAKED)
+ISR(TIMER1_OVF_vect)
+{
+ ++kernel.cycles;
+}
+
+ISR(TIMER1_COMPA_vect, ISR_NAKED)
{
struct task *t;
struct task *rtr;
uint32_t now;
uint32_t nexthit;
- int32_t timeleft;
PUSH_ALL();
- TIMSK &= ~_BV(OCIE1A); /* turn off output compare 1A */
-
- if (bit_is_set(TIFR, TOV1)) {
- TIFR |= _BV(TOV1); /* reset flag */
- ++kernel.cycles;
- }
-
now = NOW(kernel.cycles, TCNT1);
- nexthit = now + EPOCH;
+ nexthit = EPOCH + now;
/* update idle task */
- kernel.task->release = now;
kernel.task->deadline = nexthit;
rtr = kernel.task;
@@ -81,66 +75,49 @@ ISR(SCHEDULE, ISR_NAKED)
for (t = &kernel.task[1]; t <= kernel.last; t++) {
/* release tasks from time-wait-queue */
if (t->state == TIMEQ) {
- if (DISTANCE(now, t->release) < 0)
+ if (DISTANCE(t->release, now) > 0)
t->state = RUNQ;
else if (DISTANCE(t->release, nexthit) > 0)
nexthit = t->release;
}
/* find next task to run */
- if (t->state == RUNQ && \
- DISTANCE(t->deadline, rtr->deadline) > 0)
- rtr = t;
- }
-
- if (kernel.running != rtr) {
- /* switch task */
- kernel.running->spl = SPL;
- kernel.running->sph = SPH;
- SPL = rtr->spl;
- SPH = rtr->sph;
- kernel.running = rtr;
+ if (t->state == RUNQ) {
+ if (DISTANCE(t->deadline, rtr->deadline) > 0)
+ rtr = t;
+ }
}
- now = NOW(kernel.cycles, TCNT1);
- timeleft = DISTANCE(now, nexthit);
-
- if (timeleft < EPS)
- timeleft = EPS;
-
- timeleft += TCNT1;
-
- if (timeleft < 0xFFFF)
- OCR1A = timeleft;
- else if (TCNT1 > 0xFFFF - EPS)
- OCR1A = EPS;
- else
- OCR1A = 0;
-
- TIMSK |= _BV(OCIE1A);
+ /* switch task */
+ kernel.running->sp = SP;
+ SP = rtr->sp;
+ kernel.running = rtr;
+ OCR1A = (uint16_t)nexthit;
+
POP_ALL();
-
reti();
}
void
init(int stack)
{
+ cli();
+
/* Set up timer 1 */
- TCNT1 = 0; /* reset counter 1 */
- TCCR1A = 0; /* normal operation */
- TCCR1B = TIMER_FLAGS;
- TIMSK = _BV(OCIE1A);
+ TCNT1 = 0; /* reset timer */
+ TCCR1A = 0; /* normal operation */
+ TCCR1B = TIMER_FLAGS; /* prescale */
+ TIMSK = (_BV(OCIE1A) | _BV(TOIE1)); /* enable interrupts */
+ kernel.cycles = 0;
kernel.freemem = (void *)(RAMEND - stack);
kernel.last = kernel.task;
kernel.running = kernel.task;
- kernel.cycles = 0;
/* Initialize idle task (task 0) */
- kernel.running->release = 0;
kernel.running->deadline = EPOCH;
+ kernel.running->state = RUNQ;
sei();
}
@@ -150,7 +127,7 @@ exec(void (*fun)(void *), uint16_t stack, void *args)
{
struct task *t;
uint8_t *sp;
- int i;
+ uint8_t i;
cli();
@@ -158,27 +135,25 @@ exec(void (*fun)(void *), uint16_t stack, void *args)
kernel.freemem -= stack;
/* initialize stack */
- *sp-- = LO8(fun); /* store PC(lo) */
- *sp-- = HI8(fun); /* store PC(hi) */
+ *sp-- = LO8(fun); /* PC(lo) */
+ *sp-- = HI8(fun); /* PC(hi) */
- for (i = 0; i < 25; i++)
- *sp-- = 0; /* store r1-r0, SREG, r2-r23 */
+ for (i = 0; i < 25; i++) /* r1, r0, SREG, r2-r23 */
+ *sp-- = 0;
+
+ *sp-- = LO8(args); /* r24 */
+ *sp-- = HI8(args); /* r25 */
- /* Save args in r24-25 (input arguments stored in these registers) */
- *sp-- = LO8(args);
- *sp-- = HI8(args);
-
- for (i = 0; i < 6; i++)
- *sp-- = 0; /* store r26-r31 */
+ for (i = 0; i < 6; i++) /* r26-r31 */
+ *sp-- = 0;
t = ++kernel.last;
t->release = 0;
t->deadline = EPOCH;
- t->state = RUNQ;
+ t->state = TIMEQ;
- t->spl = LO8(sp); /* store stack pointer */
- t->sph = HI8(sp);
+ t->sp = (uint16_t)sp; /* SP */
SCHEDULE();
}
@@ -201,44 +176,42 @@ wait(uint8_t sema)
if (kernel.semaphore[sema] == 0) {
kernel.running->state = WAITQOFFSET + sema;
SCHEDULE();
- } else
+ } else {
--kernel.semaphore[sema];
-
- sei();
+ sei();
+ }
}
void
signal(uint8_t sema)
{
- struct task *t;
- struct task *rtr;
+ struct task *t, *rtr;
cli();
rtr = kernel.task;
for (t = &kernel.task[1]; t <= kernel.last; t++) {
- if (t->state == WAITQOFFSET + sema && \
- DISTANCE(t->deadline, rtr->deadline) > 0)
- rtr = t;
+ if (t->state == WAITQOFFSET + sema)
+ if (DISTANCE(t->deadline, rtr->deadline) > 0)
+ rtr = t;
}
if (rtr != kernel.task) {
rtr->state = RUNQ;
SCHEDULE();
- } else
+ } else {
++kernel.semaphore[sema];
-
- sei();
+ sei();
+ }
}
void
-update(uint32_t release, uint32_t deadline)
+set(uint32_t release, uint32_t deadline)
{
cli();
- if (DISTANCE(NOW(kernel.cycles, TCNT1), release) > 0)
- kernel.running->state = TIMEQ;
+ kernel.running->state = TIMEQ;
kernel.running->release = release;
kernel.running->deadline = deadline;
@@ -246,41 +219,51 @@ update(uint32_t release, uint32_t deadline)
}
void
-sleep(uint8_t type, uint32_t delay)
+update(uint32_t release, uint32_t deadline)
{
cli();
kernel.running->state = TIMEQ;
- kernel.running->release += delay;
- switch (type) {
- case SOFT:
- if (DISTANCE(kernel.running->deadline, kernel.running->release) > 0)
- kernel.running->deadline += delay;
- break;
- case HARD:
- kernel.running->deadline = kernel.running->release;
- break;
- }
+ kernel.running->release += release;
+ kernel.running->deadline = kernel.running->release + deadline;
SCHEDULE();
}
-
+
uint32_t
deadline(void)
{
- return kernel.running->deadline;
+ uint32_t ret;
+
+ cli();
+ ret = kernel.running->deadline;
+ sei();
+
+ return ret;
}
uint32_t
release(void)
{
- return kernel.running->release;
+ uint32_t ret;
+
+ cli();
+ ret = kernel.running->release;
+ sei();
+
+ return ret;
}
uint32_t
now(void)
{
- return NOW(kernel.cycles, TCNT1);
+ uint32_t ret;
+
+ cli();
+ ret = NOW(kernel.cycles, TCNT1);
+ sei();
+
+ return ret;
}
void
@@ -296,5 +279,18 @@ suspend(void)
uint8_t
running(void)
{
- return kernel.running - kernel.task;
+ uint8_t ret;
+
+ cli();
+ ret = kernel.running - kernel.task;
+ sei();
+
+ return ret;
+}
+
+void
+idle(void)
+{
+ for (;;)
+ asm volatile ("nop");
}
diff --git a/kernel/kernel.h b/kernel/kernel.h
index 2a96b6b..cadef22 100644
--- a/kernel/kernel.h
+++ b/kernel/kernel.h
@@ -19,47 +19,77 @@
#define __KERNEL_H
#ifndef TASKS
-#warning "TASKS not set, fallback to default"
+#warning TASKS not set, fallback to default
#define TASKS 8
#endif
#ifndef SEMAPHORES
-#warning "SEMAPHORES not set, fallback to default"
+#warning SEMAPHORES not set, fallback to default
#define SEMAPHORES 8
#endif
#ifndef STACK
-#warning "STACK not set, fallback to default"
+#warning STACK not set, fallback to default
#define STACK 64
#endif
#ifndef F_CPU
-#warning "F_CPU not set, fallback to default"
-#define F_CPU 1000000
+#warning F_CPU not set, fallback to default
+#define F_CPU 16000000
#endif
#ifndef PRESCALE
-#warning "PRESCALE not set, fallback to default"
+#warning PRESCALE not set, fallback to default
#define PRESCALE 1
#endif
#if (PRESCALE == 1)
-#define TIMER_FLAGS _BV(CS10)
+#define TIMER_FLAGS (_BV(CS10))
#elif (PRESCALE == 8)
-#define TIMER_FLAGS _BV(CS11)
+#define TIMER_FLAGS (_BV(CS11))
#elif (PRESCALE == 64)
#define TIMER_FLAGS (_BV(CS11) | _BV(CS10))
#elif (PRESCALE == 256)
-#define TIMER_FLAGS _BV(CS12)
+#define TIMER_FLAGS (_BV(CS12))
#elif (PRESCALE == 1024)
#define TIMER_FLAGS (_BV(CS12) | _BV(CS10))
#else
-#warning "invalid PRESCALE value"
+#error invalid PRESCALE value
#endif
-#define SEC(T) ((uint32_t)(T) * (F_CPU / PRESCALE))
-#define MSEC(T) ((uint32_t)(T) * ((F_CPU / 1000) / PRESCALE))
-#define USEC(T) ((uint32_t)(T) * ((F_CPU / 1000000) / PRESCALE))
+#define MHz ((F_CPU / 1000000) / PRESCALE)
+#define kHz ((F_CPU / 1000) / PRESCALE)
+#define Hz (F_CPU / PRESCALE)
+
+#if (!MHz)
+#error MHz value too small, adjust PRESCALE and/or F_CPU
+#endif
+
+#if (!kHz)
+#error kHz value too small, adjust PRESCALE and/or F_CPU
+#endif
+
+#if (!Hz)
+#error Hz value too small, adjust PRESCALE and/or F_CPU
+#endif
+
+#define USECMAX (INT32_MAX / MHz)
+#define MSECMAX (INT32_MAX / kHz)
+#define SECMAX (INT32_MAX / Hz)
+
+#define USEC(T) ((uint32_t)(T) * MHz)
+#define MSEC(T) ((uint32_t)(T) * kHz)
+#define SEC(T) ((uint32_t)(T) * Hz)
+
+#define SEC6(T) ((uint32_t)(T) * ((F_CPU / 1000000) / PRESCALE))
+#define SEC5(T) ((uint32_t)(T) * ((F_CPU / 100000) / PRESCALE))
+#define SEC4(T) ((uint32_t)(T) * ((F_CPU / 10000) / PRESCALE))
+#define SEC3(T) ((uint32_t)(T) * ((F_CPU / 1000) / PRESCALE))
+#define SEC2(T) ((uint32_t)(T) * ((F_CPU / 100) / PRESCALE))
+#define SEC1(T) ((uint32_t)(T) * ((F_CPU / 10) / PRESCALE))
+#define SEC0(T) ((uint32_t)(T) * ((F_CPU / 1) / PRESCALE))
+
+/* __BEGIN_DECLS */
void init(int stack);
void exec(void (*fun)(void *), uint16_t stack, void *args);
@@ -69,13 +99,18 @@ void wait(uint8_t semnbr);
void signal(uint8_t semnbr);
void suspend(void);
+void set(uint32_t release, uint32_t deadline);
void update(uint32_t release, uint32_t deadline);
-enum { SOFT, HARD };
-void sleep(uint8_t, uint32_t);
+enum Sleep { SOFT, HARD };
+enum Critical { ON, OFF };
+void sleep(enum Sleep, uint32_t);
uint32_t now(void);
uint32_t release(void);
uint32_t deadline(void);
uint8_t running(void);
+void idle(void);
+
+/* __END_DECLS */
#endif
diff --git a/kernel/lcd3.c b/kernel/lcd3.c
index 848dee9..b7bbb10 100644
--- a/kernel/lcd3.c
+++ b/kernel/lcd3.c
@@ -19,10 +19,7 @@
#include <inttypes.h>
#include <avr/io.h>
-#ifdef USE_DELAY
-#warning "using dalay routines"
#include <util/delay.h>
-#endif
#include "kernel.h"
#include "tasks.h"
@@ -39,10 +36,10 @@
#define BLINK _BV(0)
#define CURSOR_OR_DISPLAY_SHIFT _BV(4)
-#define SHIFT_CURS_LEFT (0x00 << 2)
-#define SHIFT_CURS_RIGHT (0x01 << 2)
-#define SHIFT_DISP_LEFT (0x10 << 2)
-#define SHIFT_DISP_RIGHT (0x11 << 2)
+#define SHIFT_CURS_LEFT 0
+#define SHIFT_CURS_RIGHT _BV(2)
+#define SHIFT_DISP_LEFT _BV(3)
+#define SHIFT_DISP_RIGHT (_BV(2) | _BV(3))
#define FUNCTION_SET _BV(5)
#define DATA_LENGTH_8BIT _BV(4) /* on 8 / off 4 bit */
@@ -54,20 +51,15 @@
#define SET_DDRAM_ADDRESS _BV(7)
#define BUSY_FLAG _BV(7)
-/* 3-wire interface with 74HC164 */
+/* 3-wire interface to HD44780 throuth 74HC164 */
#define PORT PORTD
#define PORTDIR DDRD
-#define DATA PD5
-#define CLOCK PD6
-#define E PD7
+#define DATA PD5
+#define CLOCK PD6
+#define E PD7
-#ifdef USE_DELAY
#define write_cmd(x, delay) do { write_byte((x), 0); _delay_us(delay); } while (0)
#define write_data(x) do { write_byte((x), 1); _delay_us(43); } while (0)
-#else
-#define write_cmd(x, delay) do { write_byte((x), 0); sleep(SOFT, USEC(delay)); } while (0)
-#define write_data(x) do { write_byte((x), 1); sleep(SOFT, USEC(43)); } while (0)
-#endif
#define move(line, row) do { write_cmd(SET_DDRAM_ADDRESS | ((line) << 6) | (row), 39); } while (0)
#define clear() do { write_cmd(CLEAR_DISPLAY, 1530); } while (0)
#define home() do { write_cmd(RETURN_HOME, 1530); } while (0)
@@ -84,7 +76,7 @@ write_byte(uint8_t byte, uint8_t rs)
uint8_t i;
for (i = 0; i < 8; i++) {
- setif(byte & (0b10000000 >> i), PORT, DATA); /* MSF */
+ setif(byte & (0x80 >> i), PORT, DATA); /* MSF */
strobe(PORT, CLOCK);
}
setif(rs, PORT, DATA);
@@ -106,66 +98,6 @@ mvputch(uint8_t line, uint8_t row, char ch)
write_data(ch);
}
-#if 0
-static char *
-itoa(int32_t n)
-{
- static char buf[12];
- char *s = &buf[11];
- uint32_t sign, u = n;
-
- *s = '\0';
-
- if ((sign = (n < 0)))
- u = ~u + 1;
-
- do
- *--s = '0' + (u % 10);
- while ((u /= 10) > 0);
-
- if (sign)
- *--s = '-';
-
- while (s != buf)
- *--s = ' ';
-
- return s;
-}
-
-static char hex[] = "0123456789ABCDEF";
-
-static char *
-itohex16(uint16_t x)
-{
- static char buf[5];
- char *s = &buf[4];
- uint8_t i;
-
- *s = '\0';
-
- for (i = 0; i < 16; i += 4)
- *--s = hex[(x >> i) & 0x0f];
-
- return s;
-}
-
-
-static char *
-itohex32(uint32_t x)
-{
- static char buf[9];
- char *s = &buf[8];
- uint8_t i;
-
- *s = '\0';
-
- for (i = 0; i < 32; i += 4)
- *--s = hex[(x >> i) & 0x0f];
-
- return s;
-}
-#endif
-
void
lcd(void *arg)
{
@@ -174,7 +106,7 @@ lcd(void *arg)
PORTDIR |= (_BV(DATA) | _BV(CLOCK) | _BV(E));
/* task init: wait >40ms */
- update(MSEC(40), MSEC(500));
+ update(now() + MSEC(40), MSEC(500));
/* 8 bit, 2 line, 5x8 font */
write_cmd(FUNCTION_SET | DATA_LENGTH_8BIT | TWO_LINES, 39);
@@ -197,6 +129,6 @@ lcd(void *arg)
for (;;) {
mvputs(0, 0, a->first);
mvputs(1, 0, a->second);
- sleep(SOFT, MSEC(40)); /* 25 Hz */
+ update(MSEC(40), MSEC(40)); /* 25Hz */
}
}
diff --git a/kernel/rgb.c b/kernel/rgb.c
index 4a963c7..5684456 100644
--- a/kernel/rgb.c
+++ b/kernel/rgb.c
@@ -17,169 +17,36 @@
#include <inttypes.h>
#include <avr/io.h>
-#include <avr/pgmspace.h>
+#include <avr/interrupt.h>
#include "kernel.h"
#include "tasks.h"
void hsv(uint8_t *, uint8_t *, uint8_t *, uint16_t, uint8_t, uint8_t);
-/* 1/sqrt(2) timing scala in usec */
-uint16_t factor[] PROGMEM = {
- 30, 30, 31, 31, 32, 32, 33, 34,
- 34, 35, 35, 36, 37, 37, 38, 39,
- 39, 40, 41, 41, 42, 43, 44, 44,
- 45, 46, 47, 48, 48, 49, 50, 51,
- 52, 53, 54, 55, 56, 57, 58, 59,
- 60, 61, 62, 63, 64, 65, 66, 68,
- 69, 70, 71, 72, 74, 75, 76, 78,
- 79, 80, 82, 83, 85, 86, 88, 89,
- 91, 92, 94, 96, 97, 99, 101, 103,
- 104, 106, 108, 110, 112, 114, 116, 118,
- 120, 122, 124, 126, 129, 131, 133, 136,
- 138, 140, 143, 145, 148, 150, 153, 156,
- 158, 161, 164, 167, 170, 173, 176, 179,
- 182, 185, 189, 192, 195, 199, 202, 206,
- 209, 213, 217, 220, 224, 228, 232, 236,
- 240, 245, 249, 253, 258, 262, 267, 272,
- 276, 281, 286, 291, 296, 301, 307, 312,
- 317, 323, 329, 334, 340, 346, 352, 358,
- 365, 371, 378, 384, 391, 398, 405, 412,
- 419, 426, 434, 441, 449, 457, 465, 473,
- 481, 490, 498, 507, 516, 525, 534, 544,
- 553, 563, 573, 583, 593, 603, 614, 625,
- 635, 647, 658, 669, 681, 693, 705, 717,
- 730, 743, 756, 769, 782, 796, 810, 824,
- 839, 853, 868, 883, 899, 915, 931, 947,
- 963, 980, 997, 1015, 1033, 1051, 1069, 1088,
- 1107, 1126, 1146, 1166, 1186, 1207, 1228, 1250,
- 1271, 1294, 1316, 1339, 1363, 1386, 1411, 1435,
- 1460, 1486, 1512, 1538, 1565, 1593, 1621, 1649,
- 1678, 1707, 1737, 1767, 1798, 1830, 1862, 1894,
- 1927, 1961, 1995, 2030, 2066, 2102, 2138, 2176,
- 2214, 2253, 2292, 2332, 2373, 2414, 2457, 2500,
-};
-
-struct bb {
- uint8_t color, r, g, b;
-} bb[] PROGMEM = {
- { 10, 0xff, 0x38, 0x00 },
- { 11, 0xff, 0x47, 0x00 },
- { 12, 0xff, 0x53, 0x00 },
- { 13, 0xff, 0x5d, 0x00 },
- { 14, 0xff, 0x65, 0x00 },
- { 15, 0xff, 0x6d, 0x00 },
- { 16, 0xff, 0x73, 0x00 },
- { 17, 0xff, 0x79, 0x00 },
- { 18, 0xff, 0x7e, 0x00 },
- { 19, 0xff, 0x83, 0x00 },
- { 20, 0xff, 0x89, 0x12 },
- { 21, 0xff, 0x8e, 0x21 },
- { 22, 0xff, 0x93, 0x2c },
- { 23, 0xff, 0x98, 0x36 },
- { 24, 0xff, 0x9d, 0x3f },
- { 25, 0xff, 0xa1, 0x48 },
- { 26, 0xff, 0xa5, 0x4f },
- { 27, 0xff, 0xa9, 0x57 },
- { 28, 0xff, 0xad, 0x5e },
- { 29, 0xff, 0xb1, 0x65 },
- { 30, 0xff, 0xb4, 0x6b },
- { 31, 0xff, 0xb8, 0x72 },
- { 32, 0xff, 0xbb, 0x78 },
- { 33, 0xff, 0xbe, 0x7e },
- { 34, 0xff, 0xc1, 0x84 },
- { 35, 0xff, 0xc4, 0x89 },
- { 36, 0xff, 0xc7, 0x8f },
- { 37, 0xff, 0xc9, 0x94 },
- { 38, 0xff, 0xcc, 0x99 },
- { 39, 0xff, 0xce, 0x9f },
- { 40, 0xff, 0xd1, 0xa3 },
- { 41, 0xff, 0xd3, 0xa8 },
- { 42, 0xff, 0xd5, 0xad },
- { 43, 0xff, 0xd7, 0xb1 },
- { 44, 0xff, 0xd9, 0xb6 },
- { 45, 0xff, 0xdb, 0xba },
- { 46, 0xff, 0xdd, 0xbe },
- { 47, 0xff, 0xdf, 0xc2 },
- { 48, 0xff, 0xe1, 0xc6 },
- { 49, 0xff, 0xe3, 0xca },
- { 50, 0xff, 0xe4, 0xce },
- { 51, 0xff, 0xe6, 0xd2 },
- { 52, 0xff, 0xe8, 0xd5 },
- { 53, 0xff, 0xe9, 0xd9 },
- { 54, 0xff, 0xeb, 0xdc },
- { 55, 0xff, 0xec, 0xe0 },
- { 56, 0xff, 0xee, 0xe3 },
- { 57, 0xff, 0xef, 0xe6 },
- { 58, 0xff, 0xf0, 0xe9 },
- { 59, 0xff, 0xf2, 0xec },
- { 60, 0xff, 0xf3, 0xef },
- { 61, 0xff, 0xf4, 0xf2 },
- { 62, 0xff, 0xf5, 0xf5 },
- { 63, 0xff, 0xf6, 0xf8 },
- { 64, 0xff, 0xf8, 0xfb },
- { 65, 0xff, 0xf9, 0xfd },
- { 66, 0xfe, 0xf9, 0xff },
- { 67, 0xfc, 0xf7, 0xff },
- { 68, 0xf9, 0xf6, 0xff },
- { 69, 0xf7, 0xf5, 0xff },
- { 70, 0xf5, 0xf3, 0xff },
- { 71, 0xf3, 0xf2, 0xff },
- { 72, 0xf0, 0xf1, 0xff },
- { 73, 0xef, 0xf0, 0xff },
- { 74, 0xed, 0xef, 0xff },
- { 75, 0xeb, 0xee, 0xff },
- { 76, 0xe9, 0xed, 0xff },
- { 77, 0xe7, 0xec, 0xff },
- { 78, 0xe6, 0xeb, 0xff },
- { 79, 0xe4, 0xea, 0xff },
- { 80, 0xe3, 0xe9, 0xff },
- { 81, 0xe1, 0xe8, 0xff },
- { 82, 0xe0, 0xe7, 0xff },
- { 83, 0xde, 0xe6, 0xff },
- { 84, 0xdd, 0xe6, 0xff },
- { 85, 0xdc, 0xe5, 0xff },
- { 86, 0xda, 0xe4, 0xff },
- { 87, 0xd9, 0xe3, 0xff },
- { 88, 0xd8, 0xe3, 0xff },
- { 89, 0xd7, 0xe2, 0xff },
- { 90, 0xd6, 0xe1, 0xff },
-};
-
void
rgb(void *arg)
{
struct rgbarg *a = (struct rgbarg *)arg;
uint16_t i = 0;
- uint8_t v;
+ uint8_t r, g, b;
+
+ cli();
+ a->m = 255 >> 4;
+ sei();
- update(0, MSEC(370));
+ update(now(), MSEC(500));
for (;;) {
-#if 1
i = (i + 1) % 360;
- #if 0
- v = i % 120;
- v = (v < 60) ? 255 - 2 * v : 15 + 2 * v;
- #else
- v = 255;
- #endif
+ hsv(&r, &g, &b, i, 255, 255);
- hsv(a->r, a->g, a->b, i, 255, v);
- sleep(SOFT, MSEC(83));
-#else
- i = (i + 1) % 162;
- if (i > 80)
- v = 161 - i;
- else
- v = i;
- //wait(0);
- *a->r = pgm_read_byte(&bb[v].r);
- *a->g = pgm_read_byte(&bb[v].g);
- *a->b = pgm_read_byte(&bb[v].b);
- //signal(0);
+ cli();
+ a->r = r >> 4;
+ a->g = g >> 4;
+ a->b = b >> 4;
+ sei();
- sleep(SOFT, MSEC(370));
-#endif
+ update(MSEC(500), MSEC(500));
}
}
@@ -187,29 +54,32 @@ void
pwm(void *arg)
{
struct pwmarg *a = (struct pwmarg *)arg;
- uint16_t on, off, maxval;;
- uint32_t n = now();
+ uint16_t maxval, on, off;
DDRB |= _BV(a->pin);
PORTB &= ~_BV(a->pin);
- maxval = pgm_read_word(&factor[255]);
- update(n, n + USEC(maxval));
+#define DL MSEC(1)
+
+ cli();
+ maxval = *a->mval;
+ sei();
+ update(now(), DL);
for (;;) {
- //wait(0);
- on = pgm_read_word(&factor[*a->value]);
- //signal(0);
- off = maxval - on;
+ cli();
+ on = *a->value;
+ sei();
- if (*a->value > 0) {
+ if (on) {
PORTB |= _BV(a->pin);
- sleep(HARD, USEC(on));
+ update(MSEC(on), DL);
}
- if (*a->value < 255) {
+ off = maxval - on;
+ if (off) {
PORTB &= ~_BV(a->pin);
- sleep(HARD, USEC(off));
+ update(MSEC(off), DL);
}
}
}
diff --git a/kernel/stack.h b/kernel/stack.h
index 0f44954..b53c870 100644
--- a/kernel/stack.h
+++ b/kernel/stack.h
@@ -18,9 +18,6 @@
#ifndef __STACK_H
#define __STACK_H
-/* average latency in cycles */
-#define LATENCY 72
-
/* 68 cycles */
#define PUSH_ALL() asm volatile ( \
"push r1 \n" \
diff --git a/kernel/tasks.h b/kernel/tasks.h
index f6030b3..9fb27da 100644
--- a/kernel/tasks.h
+++ b/kernel/tasks.h
@@ -42,12 +42,16 @@
#endif
struct rgbarg {
- uint8_t *r, *g, *b;
+ uint8_t r;
+ uint8_t g;
+ uint8_t b;
+ uint8_t m;
};
struct pwmarg {
uint8_t *value;
uint8_t pin;
+ uint8_t *mval;
};
struct adcarg {
@@ -62,19 +66,10 @@ struct lcdarg {
uint8_t x, y;
};
-struct clockarg {
- uint8_t d, h, m, s;
-};
-
struct ppmarg {
uint16_t *value;
};
-struct ctrlarg {
- struct lcdarg *lcd;
- struct clockarg *clock;
-};
-
void init_uart(void);
int uart_getchar(void);
int uart_putchar(char);
@@ -87,6 +82,5 @@ void adc(void *);
void ppm(void *);
void cmd(void *);
void clock(void *);
-void ctrl(void *);
#endif
diff --git a/kernel/uart.c b/kernel/uart.c
index 0d64d50..defd552 100644
--- a/kernel/uart.c
+++ b/kernel/uart.c
@@ -84,6 +84,7 @@ ISR(SIG_UART_RECV)
switch (c) {
case 'R': /* reboot */
+ case '-': /* reboot */
wdt_enable(WDTO_15MS);
break;
case 'D': /* dump */