From 58a011ea08a55bee223a0028ddb6237e466b93d0 Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Tue, 22 Mar 2011 02:51:32 +0000 Subject: tweak api --- kernel/adc.c | 7 +---- kernel/heartbeat.c | 15 +++-------- kernel/kernel.c | 57 ++++++++++++++++++++++++++-------------- kernel/kernel.h | 3 ++- kernel/lcd3.c | 31 +++++----------------- kernel/main.c | 17 ++++++------ kernel/ppm.c | 76 ++++++++++++++++++++++++------------------------------ kernel/tasks.h | 2 +- 8 files changed, 94 insertions(+), 114 deletions(-) (limited to 'kernel') 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 #include +#include #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 -- cgit v1.2.3