aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitri Sokolyuk <demon@dim13.org>2011-03-22 02:51:32 +0000
committerDimitri Sokolyuk <demon@dim13.org>2011-03-22 02:51:32 +0000
commit58a011ea08a55bee223a0028ddb6237e466b93d0 (patch)
tree591f0ebf970820580c65912e0b893401d2a20f56
parentd3e3547ebab9a28e7599ed218a13876a2289c122 (diff)
tweak api
-rw-r--r--kernel/adc.c7
-rw-r--r--kernel/heartbeat.c15
-rw-r--r--kernel/kernel.c57
-rw-r--r--kernel/kernel.h3
-rw-r--r--kernel/lcd3.c31
-rw-r--r--kernel/main.c17
-rw-r--r--kernel/ppm.c76
-rw-r--r--kernel/tasks.h2
8 files changed, 94 insertions, 114 deletions
diff --git a/kernel/adc.c b/kernel/adc.c
index bacb576..cde31ff 100644
--- a/kernel/adc.c
+++ b/kernel/adc.c
@@ -37,9 +37,6 @@ void
adc(void *arg)
{
struct adcarg *a = (struct adcarg *)arg;
- uint32_t r = release();
- uint32_t d = deadline();
- uint16_t v;
uint8_t i;
ADCSRA |= (_BV(ADEN) | ADC_FLAGS);
@@ -50,8 +47,6 @@ adc(void *arg)
for (i = 0; i < ADCCHANNELS; i++)
a->value[i] = rdadc(i);
signal(0);
- r = d;
- d += MSEC(10) * ADCCHANNELS;
- update(r, d);
+ period(MSEC(8 * ADCCHANNELS));
}
}
diff --git a/kernel/heartbeat.c b/kernel/heartbeat.c
index 6960e63..64f3182 100644
--- a/kernel/heartbeat.c
+++ b/kernel/heartbeat.c
@@ -26,28 +26,21 @@ void
heartbeat(void *arg)
{
/* 80bpm: 100ms on, 50ms off, 100ms on, 500ms off */
- uint32_t d = deadline();
- uint32_t r = release();
DDRB |= _BV(PIN);
PORTB &= ~_BV(PIN);
for (;;) {
PORTB ^= _BV(PIN);
- r += MSEC(100);
- update(r, d);
+ snooze(MSEC(100));
PORTB ^= _BV(PIN);
- r += MSEC(50);
- update(r, d);
+ snooze(MSEC(50));
PORTB ^= _BV(PIN);
- r += MSEC(100);
- update(r, d);
+ snooze(MSEC(100));
PORTB ^= _BV(PIN);
- r += MSEC(500);
- d = r + MSEC(750);
- update(r, d);
+ period(MSEC(750));
}
}
diff --git a/kernel/kernel.c b/kernel/kernel.c
index 1d37d97..ad21de3 100644
--- a/kernel/kernel.c
+++ b/kernel/kernel.c
@@ -25,7 +25,7 @@
#include "kernel.h"
#include "stack.h"
-enum { TERMINATED, READYQ, TIMEQ, WAITQOFFSET };
+enum { TERMINATED, RUNQ, TIMEQ, WAITQOFFSET };
#define LO8(x) ((uint8_t)((uint16_t)(x)))
#define HI8(x) ((uint8_t)((uint16_t)(x) >> 8))
@@ -40,12 +40,12 @@ struct task {
uint8_t sph;
uint32_t release;
uint32_t deadline;
+ uint32_t period;
uint8_t state;
};
struct kernel {
struct task *running;
- struct task *prev;
struct task *idle;
struct task *first;
struct task *last;
@@ -85,13 +85,13 @@ ISR(SCHEDULE, ISR_NAKED)
/* release tasks from time-wait-queue */
if (t->state == TIMEQ) {
if (DISTANCE(now, t->release) < 0)
- t->state = READYQ;
+ t->state = RUNQ;
else if (DISTANCE(t->release, nexthit) > 0)
nexthit = t->release;
}
/* find next task to run */
- if (t->state == READYQ && \
+ if (t->state == RUNQ && \
DISTANCE(t->deadline, rtr->deadline) > 0)
rtr = t;
}
@@ -102,7 +102,6 @@ ISR(SCHEDULE, ISR_NAKED)
kernel.running->sph = SPH;
SPL = rtr->spl;
SPH = rtr->sph;
- kernel.prev = kernel.running;
kernel.running = rtr;
}
@@ -142,7 +141,6 @@ init(int idlestack)
kernel.first = &kernel.task[1];
kernel.last = kernel.idle;
kernel.running = kernel.idle;
- kernel.prev = kernel.idle;
kernel.cycles = 0;
/* Initialize idle task (task 0) */
@@ -164,11 +162,6 @@ task(void (*fun)(void *), uint16_t stack, uint32_t release, uint32_t deadline, v
sp = kernel.freemem;
kernel.freemem -= stack;
- /*
- *sp-- = 'A';
- *sp-- = 'A';
- */
-
/* initialize stack */
*sp-- = LO8(fun); /* store PC(lo) */
*sp-- = HI8(fun); /* store PC(hi) */
@@ -186,7 +179,8 @@ task(void (*fun)(void *), uint16_t stack, uint32_t release, uint32_t deadline, v
t = ++kernel.last;
t->release = release;
- t->deadline = deadline;
+ t->deadline = deadline + release;
+ t->period = deadline;
t->state = TIMEQ;
t->spl = LO8(sp); /* store stack pointer */
@@ -236,7 +230,7 @@ signal(uint8_t sema)
}
if (rtr != kernel.idle) {
- rtr->state = READYQ;
+ rtr->state = RUNQ;
SCHEDULE();
} else
++kernel.semaphore[sema];
@@ -251,7 +245,36 @@ update(uint32_t release, uint32_t deadline)
kernel.running->state = TIMEQ;
kernel.running->release = release;
- kernel.running->deadline = deadline > release ? deadline : release;
+ kernel.running->deadline = deadline;
+
+ SCHEDULE();
+}
+
+void
+snooze(uint32_t delay)
+{
+ cli();
+
+ kernel.running->state = TIMEQ;
+ kernel.running->release += delay;
+
+ while (DISTANCE(kernel.running->deadline, kernel.running->release) > 0)
+ kernel.running->deadline += kernel.running->period;
+
+ SCHEDULE();
+}
+
+void
+period(uint32_t t)
+{
+ cli();
+
+ if (t)
+ kernel.running->period = t;
+
+ kernel.running->state = TIMEQ;
+ kernel.running->release = kernel.running->deadline;
+ kernel.running->deadline += kernel.running->period;
SCHEDULE();
}
@@ -289,9 +312,3 @@ running(void)
{
return kernel.running - kernel.idle;
}
-
-uint8_t
-previous(void)
-{
- return kernel.prev - kernel.idle;
-}
diff --git a/kernel/kernel.h b/kernel/kernel.h
index feab5b0..b7fde9d 100644
--- a/kernel/kernel.h
+++ b/kernel/kernel.h
@@ -69,12 +69,13 @@ void wait(uint8_t semnbr);
void signal(uint8_t semnbr);
void update(uint32_t release, uint32_t deadline);
+void snooze(uint32_t delay);
+void period(uint32_t t);
void suspend(void);
uint32_t now(void);
uint32_t release(void);
uint32_t deadline(void);
uint8_t running(void);
-uint8_t previous(void);
#endif
diff --git a/kernel/lcd3.c b/kernel/lcd3.c
index 5fcae11..89edc94 100644
--- a/kernel/lcd3.c
+++ b/kernel/lcd3.c
@@ -17,6 +17,7 @@
#include <inttypes.h>
#include <avr/io.h>
+#include <util/delay.h>
#include "kernel.h"
#include "tasks.h"
@@ -55,14 +56,10 @@
#define CLOCK PD6
#define E PD7
-struct lcdargs {
- uint32_t d;
- uint32_t r;
-} lcdargs;
-
-#define snooze(t) do { lcdargs.r += USEC(t); update(lcdargs.r, lcdargs.d); } while (0)
-#define write_cmd(x, delay) do { write_byte((x), 0); snooze(delay); } while (0)
-#define write_data(x) do { write_byte((x), 1); snooze(43); } while (0)
+#define write_cmd(x, delay) do { write_byte((x), 0); snooze(USEC(delay)); } while (0)
+#define write_data(x) do { write_byte((x), 1); snooze(USEC(43)); } while (0)
+//#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)
#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)
@@ -163,14 +160,11 @@ void
lcd(void *arg)
{
struct lcdarg *a = (struct lcdarg *)arg;
- uint8_t i, t;
PORTDIR |= (_BV(DATA) | _BV(CLOCK) | _BV(E));
/* task init: wait >40ms */
-
- lcdargs.d = deadline();
- lcdargs.r = release();
+ snooze(MSEC(40));
/* 8 bit, 2 line, 5x8 font */
write_cmd(FUNCTION_SET | DATA_LENGTH_8BIT | TWO_LINES, 39);
@@ -188,19 +182,8 @@ lcd(void *arg)
home();
for (;;) {
- /*
- t = previous() - 1; // 0 is idle
- for (i = 0; i < TASKS; i++)
- mvputch(0, 5 + i, t == i ? '1' + t : '-');
-
- mvputs(1, 5, itohex(now()));
- */
-
mvputs(0, 0, itoa(a->adc[0]));
mvputs(1, 0, itoa(a->adc[1]));
-
- lcdargs.r = lcdargs.d + MSEC(100);
- lcdargs.d += MSEC(50);
- update(lcdargs.r, lcdargs.d);
+ period(MSEC(50));
}
}
diff --git a/kernel/main.c b/kernel/main.c
index 73d4c01..d06dd8e 100644
--- a/kernel/main.c
+++ b/kernel/main.c
@@ -42,16 +42,17 @@ main()
semaphore(0, 1);
- task(heartbeat, STACK, SEC(0), MSEC(10), 0);
/*
- task(rgb, STACK, SEC(0), MSEC(10), &rgbargs);
- task(pwm, STACK, SEC(0), MSEC(10), &pwmargs[0]);
- task(pwm, STACK, SEC(0), MSEC(10), &pwmargs[1]);
- task(pwm, STACK, SEC(0), MSEC(10), &pwmargs[2]);
+ task(rgb, STACK, MSEC(10), &rgbargs);
+ task(pwm, STACK, MSEC(10), &pwmargs[0]);
+ task(pwm, STACK, MSEC(10), &pwmargs[1]);
+ task(pwm, STACK, MSEC(10), &pwmargs[2]);
*/
- task(lcd, STACK, MSEC(40), SEC(1), &lcdarg);
- task(adc, STACK, MSEC(0), MSEC(20), &adcarg);
- task(ppm, STACK, MSEC(0), MSEC(20), &ppmarg);
+
+ task(heartbeat, STACK, MSEC(0), MSEC(750), 0);
+ task(adc, STACK, MSEC(1), MSEC(60), &adcarg);
+ task(ppm, STACK, MSEC(3), MSEC(20), &ppmarg);
+ task(lcd, STACK, MSEC(7), MSEC(100), &lcdarg);
for (;;);
diff --git a/kernel/ppm.c b/kernel/ppm.c
index 62920e8..3af03a2 100644
--- a/kernel/ppm.c
+++ b/kernel/ppm.c
@@ -24,39 +24,7 @@
#define OFF PORTB &= ~_BV(PB1)
#if 0
-void
-ppm(void *arg)
-{
- struct ppmarg *a = (struct ppmarg *)arg;
- uint32_t r = release();
- uint32_t d = deadline();
- uint32_t t;
- uint32_t s;
- uint8_t i;
-
- DDRB |= _BV(DDB1);
- PORTB &= ~_BV(PB1); /* high is low */
-
- /* frame length 22.5ms, channel 0.7-1.7ms, stop 0.3 ms */
-
- for (;;) {
- s = 0;
-
- t = (uint32_t)a->value[i] * MSEC(1) / 0x3ff;
- s += MSEC(1) + t;
-
- /* channel frame 0.7..1.7ms high */
- OFF;
- r = d += MSEC(1) + t;
- update(r, d);
-
- /* stop frame 0.3ms low */
- ON;
- r = d += MSEC(25) - t - MSEC(1);
- update(r, d);
- }
-}
-#endif
+uint32_t buffer[ADCCHANNELS];
void
ppm(void *arg)
@@ -70,37 +38,59 @@ ppm(void *arg)
DDRB |= _BV(DDB1);
PORTB &= ~_BV(PB1); /* high is low */
- /* frame length 22.5ms, channel 0.7-1.7ms, stop 0.3 ms */
+ /* frame length 20ms, channel 0.7-1.7ms, stop 0.3 ms */
for (;;) {
/* start frame 0.3ms low */
- OFF;
+ ON;
r = d += USEC(300);
update(r, d);
wait(0);
- for (i = 0, t = 0; i < ADCCHANNELS; i++)
- t += a->value[i];
+ for (i = 0, t = 0; i < ADCCHANNELS; i++) {
+ buffer[i] = a->value[i];
+ t += buffer[i];
+ }
+ signal(0);
/* sync frame */
- ON;
- //r = d += USEC(22500) - MSEC(t) / 0x3ff - MSEC(ADCCHANNELS) - USEC(300);
+ OFF;
r = d += MSEC(20) - MSEC(t) / 0x3ff - MSEC(ADCCHANNELS) - USEC(300);
update(r, d);
for (i = 0; i < ADCCHANNELS; i++) {
-
/* start frame 0.3ms low */
- OFF;
+ ON;
r = d += USEC(300);
update(r, d);
/* channel frame 0.7..1.7ms high */
- ON;
- r = d += USEC(700) + MSEC(a->value[i]) / 0x3ff;
+ OFF;
+ r = d += USEC(700) + MSEC(buffer[i]) / 0x3ff;
update(r, d);
}
+
+ }
+}
+#else
+void
+ppm(void *arg)
+{
+ struct ppmarg *a = (struct ppmarg *)arg;
+ uint32_t t;
+
+ DDRB |= _BV(DDB1);
+ PORTB &= ~_BV(PB1);
+
+ for (;;) {
+ wait(0);
+ t = MSEC(1) + MSEC(a->value[0]) / 0x3ff;
signal(0);
+ period(MSEC(20));
+ PORTB ^= _BV(PB1);
+ snooze(t);
+ PORTB ^= _BV(PB1);
}
}
+#endif
diff --git a/kernel/tasks.h b/kernel/tasks.h
index 0b6795f..6e6ea43 100644
--- a/kernel/tasks.h
+++ b/kernel/tasks.h
@@ -19,7 +19,7 @@
#define __TASKS_H
#define ADCCHANNELS 6
-#define ADCPRESCALE 8
+#define ADCPRESCALE 128
#if (ADCPRESCALE == 1)
#define ADC_FLAGS 0