aboutsummaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorDimitri Sokolyuk <demon@dim13.org>2011-03-18 16:29:22 +0000
committerDimitri Sokolyuk <demon@dim13.org>2011-03-18 16:29:22 +0000
commit8be79f666b7be5e603e73dc443b7141a65da7cd9 (patch)
tree1ebcfa94e9947160902b9423a349297a5a5bed6e /kernel
parent577488e08517172c1e926b6f3fb15a4ca9f6633f (diff)
ppm
Diffstat (limited to 'kernel')
-rw-r--r--kernel/Makefile3
-rw-r--r--kernel/adc.c8
-rw-r--r--kernel/lcd3.c29
-rw-r--r--kernel/main.c12
-rw-r--r--kernel/ppm.c107
-rw-r--r--kernel/rgb.c10
-rw-r--r--kernel/tasks.h11
7 files changed, 160 insertions, 20 deletions
diff --git a/kernel/Makefile b/kernel/Makefile
index 0807a73..a6f49f2 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -1,7 +1,8 @@
# $Id$
PROG = kernel
-SRCS = kernel.c main.c uart.c heartbeat.c rgb.c hsv.c lcd3.c adc.c
+SRCS = kernel.c main.c uart.c heartbeat.c rgb.c hsv.c lcd3.c \
+ adc.c ppm.c
HEADERS = kernel.h stack.h
MCU_TARGET = atmega8
F_CPU = 16000000
diff --git a/kernel/adc.c b/kernel/adc.c
index 0037756..bacb576 100644
--- a/kernel/adc.c
+++ b/kernel/adc.c
@@ -39,15 +39,19 @@ 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);
- /* ADMUX |= _BV(REFS0); */
+// ADMUX |= _BV(REFS0);
for (;;) {
+ wait(0);
for (i = 0; i < ADCCHANNELS; i++)
a->value[i] = rdadc(i);
- r = d += MSEC(1);
+ signal(0);
+ r = d;
+ d += MSEC(10) * ADCCHANNELS;
update(r, d);
}
}
diff --git a/kernel/lcd3.c b/kernel/lcd3.c
index b4125b1..5fcae11 100644
--- a/kernel/lcd3.c
+++ b/kernel/lcd3.c
@@ -126,10 +126,27 @@ itoa(int32_t n)
return s;
}
+static char hex[] = "0123456789ABCDEF";
+
static char *
-itohex(uint32_t x)
+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 hex[] = "0123456789ABCDEF";
static char buf[9];
char *s = &buf[8];
uint8_t i;
@@ -170,9 +187,6 @@ lcd(void *arg)
home();
- mvputs(0, 0, "ADC0");
- mvputs(1, 0, "ADC1");
-
for (;;) {
/*
t = previous() - 1; // 0 is idle
@@ -181,8 +195,9 @@ lcd(void *arg)
mvputs(1, 5, itohex(now()));
*/
- mvputs(0, 5, itohex(a->adc[0]));
- mvputs(1, 5, itohex(a->adc[1]));
+
+ mvputs(0, 0, itoa(a->adc[0]));
+ mvputs(1, 0, itoa(a->adc[1]));
lcdargs.r = lcdargs.d + MSEC(100);
lcdargs.d += MSEC(50);
diff --git a/kernel/main.c b/kernel/main.c
index 1588254..73d4c01 100644
--- a/kernel/main.c
+++ b/kernel/main.c
@@ -31,6 +31,7 @@ struct pwmarg pwmargs[] = {
};
struct adcarg adcarg = { adcval };
struct lcdarg lcdarg = { 0, 0, adcval };
+struct ppmarg ppmarg = { adcval };
int
main()
@@ -39,13 +40,18 @@ main()
init_uart();
+ semaphore(0, 1);
+
task(heartbeat, STACK, SEC(0), MSEC(10), 0);
+ /*
task(rgb, STACK, SEC(0), MSEC(10), &rgbargs);
- task(cpwm, STACK, SEC(0), MSEC(10), &pwmargs[0]);
- task(cpwm, STACK, SEC(0), MSEC(10), &pwmargs[1]);
- task(cpwm, STACK, SEC(0), MSEC(10), &pwmargs[2]);
+ 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(lcd, STACK, MSEC(40), SEC(1), &lcdarg);
task(adc, STACK, MSEC(0), MSEC(20), &adcarg);
+ task(ppm, STACK, MSEC(0), MSEC(20), &ppmarg);
for (;;);
diff --git a/kernel/ppm.c b/kernel/ppm.c
new file mode 100644
index 0000000..3a6e032
--- /dev/null
+++ b/kernel/ppm.c
@@ -0,0 +1,107 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2011 Dimitri Sokolyuk <demon@dim13.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <inttypes.h>
+#include <avr/io.h>
+#include "kernel.h"
+#include "tasks.h"
+
+#define ON PORTB |= _BV(PB1)
+#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
+
+void
+ppm(void *arg)
+{
+ struct ppmarg *a = (struct ppmarg *)arg;
+ uint32_t r = release();
+ uint32_t d = deadline();
+ uint32_t t;
+ 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 (;;) {
+ /* start frame 0.3ms low */
+ OFF;
+ r = d += USEC(300);
+ update(r, d);
+
+ wait(0);
+ for (i = 0, t = 0; i < ADCCHANNELS; i++)
+ t += a->value[i];
+
+ /* sync frame */
+ ON;
+ //r = d += USEC(22500) - MSEC(t) / 0x3ff - MSEC(ADCCHANNELS) - USEC(300);
+ //r = d += MSEC(20) - MSEC(t) / 0x3ff - MSEC(ADCCHANNELS) - USEC(300);
+ r = d += USEC(22500) - MSEC(t >> 2) / 0xff - MSEC(ADCCHANNELS) - USEC(300);
+ update(r, d);
+
+ for (i = 0; i < ADCCHANNELS; i++) {
+
+ /* start frame 0.3ms low */
+ OFF;
+ r = d += USEC(300);
+ update(r, d);
+
+ /* channel frame 0.7..1.7ms high */
+ ON;
+ r = d += USEC(700) + MSEC(a->value[i] >> 2) / 0xff;
+ update(r, d);
+ }
+ signal(0);
+
+ }
+}
diff --git a/kernel/rgb.c b/kernel/rgb.c
index 06bd694..cbcb0c1 100644
--- a/kernel/rgb.c
+++ b/kernel/rgb.c
@@ -38,14 +38,14 @@ rgb(void *arg)
hsv(a->r, a->g, a->b, i, 255, v);
- r = d + MSEC(28);
- d = r + MSEC(2);
+ r = d;
+ d += MSEC(28);
update(r, d);
}
}
void
-cpwm(void *arg)
+pwm(void *arg)
{
#define SCALE 4
struct pwmarg *a = (struct pwmarg *)arg;
@@ -58,13 +58,13 @@ cpwm(void *arg)
for (;;) {
if (*a->value > 0) {
PORTB |= _BV(a->pin);
- r = d += USEC(*a->value << SCALE);
+ d = r += USEC(*a->value << SCALE);
update(r, d);
}
if (*a->value < 255) {
PORTB &= ~_BV(a->pin);
- r = d += USEC((255 - *a->value) << SCALE);
+ d = r += USEC((255 - *a->value) << SCALE);
update(r, d);
}
}
diff --git a/kernel/tasks.h b/kernel/tasks.h
index cf386c7..0b6795f 100644
--- a/kernel/tasks.h
+++ b/kernel/tasks.h
@@ -19,7 +19,7 @@
#define __TASKS_H
#define ADCCHANNELS 6
-#define ADCPRESCALE 32
+#define ADCPRESCALE 8
#if (ADCPRESCALE == 1)
#define ADC_FLAGS 0
@@ -52,6 +52,8 @@ struct pwmarg {
struct adcarg {
uint16_t *value;
+ uint16_t *max;
+ uint16_t *min;
};
struct lcdarg {
@@ -60,12 +62,17 @@ struct lcdarg {
uint16_t *adc;
};
+struct ppmarg {
+ uint16_t *value;
+};
+
void init_uart(void);
void heartbeat(void *);
void rgb(void *);
-void cpwm(void *);
+void pwm(void *);
void lcd(void *);
void adc(void *);
+void ppm(void *);
#endif