diff --git a/.depend b/.depend index 7a5fa2b..ed9730b 100644 --- a/.depend +++ b/.depend @@ -1,6 +1,7 @@ task.o: task.c task.h stm8.h main.o: main.c gt3b.h stm8.h task.h -ppm.o: ppm.c ppm.h gt3b.h stm8.h task.h +ppm.o: ppm.c ppm.h gt3b.h stm8.h task.h menu.h \ + calc.h lcd.o: lcd.c lcd.h gt3b.h stm8.h task.h input.o: input.c input.h gt3b.h stm8.h task.h menu.h buzzer.o: buzzer.c buzzer.h gt3b.h stm8.h task.h diff --git a/calc.c b/calc.c index b48532d..62d5d5c 100644 --- a/calc.c +++ b/calc.c @@ -23,3 +23,25 @@ #include "ppm.h" + +// CALC task +TASK(CALC, 256); +static void calc_loop(void); + + +// initialize CALC task +void calc_init(void) { + build(CALC); + activate(CALC, calc_loop); + sleep(CALC); // nothing to do yet +} + + + + +// calculate new PPM values from ADC and internal variables +// called for each PPM cycle +static void calc_loop(void) { + +} + diff --git a/calc.h b/calc.h index 688ffb8..11f1fe6 100644 --- a/calc.h +++ b/calc.h @@ -24,6 +24,9 @@ #include "gt3b.h" +// CALC task +E_TASK(CALC); + #endif diff --git a/main.c b/main.c index 51fa0d4..9f1fda4 100644 --- a/main.c +++ b/main.c @@ -30,6 +30,7 @@ extern void buzzer_init(void); extern void timer_init(void); extern void task_init(void); extern void eeprom_init(void); +extern void calc_init(void); extern void menu_init(void); @@ -66,6 +67,7 @@ void main(void) { ppm_init(); timer_init(); lcd_init(); + calc_init(); // enable interrupts rim(); diff --git a/menu.c b/menu.c index 1b9b2d4..9103900 100644 --- a/menu.c +++ b/menu.c @@ -25,12 +25,16 @@ +_Bool menu_takes_adc; + // calibrate menu static void calibrate(void) { + menu_takes_adc = 1; + menu_takes_adc = 0; } diff --git a/menu.h b/menu.h index 8d3a4bf..36d3211 100644 --- a/menu.h +++ b/menu.h @@ -29,6 +29,9 @@ #define MENU OPER +// menu tasks will be handling ADC now (for calibrate) +extern _Bool menu_takes_adc; + #endif diff --git a/ppm.c b/ppm.c index 1154c20..db6c4c3 100644 --- a/ppm.c +++ b/ppm.c @@ -28,9 +28,11 @@ #include #include "ppm.h" +#include "menu.h" +#include "calc.h" -// TIM3 prescalers and multiply (1000x) values to get raw TIM3 values +// TIM3 prescalers and multiply (1000x more) values to get raw TIM3 values // also SPACE values for 300us space signal // about 3.5ms max for servo pulse #define PPM_PSC_SERVO 0x00 @@ -45,6 +47,16 @@ #define PPM_FRAME_LENGTH 22500 +// channel variables +u8 channels = 3; // number of channels +static u8 channels2; // number of channels * 2 (for compare in ppm_interrupt, it is quicker this way) +static u8 ppm_channel2; // next PPM channel to send (0 is SYNC), step 2 +static _Bool ppm_enabled; // set to 1 when first ppm values was computed +// PPM values computed for direct seting to TIM3 registers +// 0 is SYNC pulse length and then channels 1-... +static u8 ppm_values[2*(MAX_CHANNELS + 1)]; // as bytes for ppm_interrupt + + // initialize PPM pin and timer 3 void ppm_init(void) { IO_OP(D, 0); // PPM output pin, TIM3_CH2 @@ -62,22 +74,12 @@ void ppm_init(void) { TIM3_CCR2L = hi8(PPM_300US_SYNC); TIM3_ARRH = hi8(PPM_MUL_SYNC * 20); TIM3_ARRL = lo8(PPM_MUL_SYNC * 20); + + // internal variables init + channels2 = (u8)(channels << 1); } -// channel variables -u8 channels = 3; // number of channels -u8 channels2 = 6; // numger of channels * 2 (for compare in ppm_interrupt) -u8 ppm_channel2; // next PPM channel to send (0 is SYNC), step 2 -_Bool ppm_enabled; // set to 1 when first ppm values was computed -_Bool ppm_update_values; // flag set when new PPM values was computed -// PPM values computed for direct set to TIM3 registers -// 0 is SYNC pulse length and then channels 1-... -u8 ppm_values[2*(MAX_CHANNELS + 1)]; // as bytes for ppm_interrupt -// new PPM values, copied to ppm_values at start of PPM frame -u16 ppm_values_new[MAX_CHANNELS + 1]; // as words for easy assign - - /* TIM3 overflow interrupt set next prescaler, output compare and overflow values to @@ -87,7 +89,16 @@ u16 ppm_values_new[MAX_CHANNELS + 1]; // as words for easy assign BRES(TIM3_SR1, 0); // erase interrupt flag if (ppm_channel2) { - // servo channel + if (ppm_channel2 == 2) { + // will be setting channel1 servo, so we are now generating + // SYNC signal in HW + // wakeup CALC task to compute new PPM values + // values for ARR registers will be updated after calculate done + // (and when we are still generating SYNC pulse) + if (!menu_takes_adc) + awake(CALC); + } + // set servo channel TIM3_PSCR = PPM_PSC_SERVO; TIM3_CCR2H = hi8(PPM_300US_SERVO); TIM3_CCR2L = lo8(PPM_300US_SERVO); @@ -101,12 +112,7 @@ u16 ppm_values_new[MAX_CHANNELS + 1]; // as words for easy assign return; } - // SYNC signal - if (ppm_update_values) { - // new values computed, copy them - memcpy(ppm_values, ppm_values_new, 2*(MAX_CHANNELS + 1)); - ppm_update_values = 0; - } + // set SYNC signal TIM3_PSCR = PPM_PSC_SYNC; TIM3_CCR2H = hi8(PPM_300US_SYNC); TIM3_CCR2L = lo8(PPM_300US_SYNC); @@ -130,7 +136,19 @@ void ppm_set_value(u8 channel, u16 microsec01) { ppm_microsecs01 += microsec01; // ARR must be set to computed value - 1, that is why we are substracting // 5000, it is quicker way to "add 5000" and then substract 1 from result - ppm_values_new[channel] = (u16)(((u32)microsec01 * PPM_MUL_SERVO - 5000) / 10000); + *(u16 *)(&ppm_values[(u8)(channel << 1)]) = + (u16)(((u32)microsec01 * PPM_MUL_SERVO - 5000) / 10000); + // for first channel, when we are still in HW SYNC generate, update + // new ARR values to get it applied now + if (channel == 1) { + sim(); + if (ppm_channel2 == 4) { + // next will channel2, so we have channel1 in ARR now + TIM3_ARRH = ppm_values[2]; + TIM3_ARRL = ppm_values[3]; + } + rim(); + } } @@ -140,8 +158,9 @@ void ppm_set_value(u8 channel, u16 microsec01) { void ppm_calc_sync(void) { // ARR must be set to computed value - 1, that is why we are substracting // 5000, it is quicker way to "add 5000" and then substract 1 from result - ppm_values_new[0] = (u16)(((10 * (u32)PPM_FRAME_LENGTH - ppm_microsecs01) * PPM_MUL_SYNC - 5000) / 10000); - ppm_update_values = 1; + *(u16 *)(&ppm_values[0]) = + (u16)(((10 * (u32)PPM_FRAME_LENGTH - ppm_microsecs01) * PPM_MUL_SYNC + - 5000) / 10000); ppm_microsecs01 = 0; // for first ppm values, enable timer if (ppm_enabled) return;