From 8be79f666b7be5e603e73dc443b7141a65da7cd9 Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Fri, 18 Mar 2011 16:29:22 +0000 Subject: ppm --- kernel/Makefile | 3 +- kernel/adc.c | 8 +++-- kernel/lcd3.c | 29 +++++++++++---- kernel/main.c | 12 +++++-- kernel/ppm.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ kernel/rgb.c | 10 +++--- kernel/tasks.h | 11 ++++-- 7 files changed, 160 insertions(+), 20 deletions(-) create mode 100644 kernel/ppm.c (limited to 'kernel') 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 + * + * 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 +#include +#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 -- cgit v1.2.3