M2DIR=../..
include $(M2DIR)/software/common.mak
-OBJECTS=crt0.o isr.o dvisampler0.o dvisampler1.o main.o
+OBJECTS=crt0.o isr.o time.o dvisampler0.o dvisampler1.o main.o
all: videomixer.bin
#include <hw/csr.h>
#include <hw/flags.h>
+#include "time.h"
#include "dvisamplerX.h"
#define FRAMEBUFFER_COUNT 4
}
static int dvisamplerX_locked;
-
-static int elapsed(int period)
-{
- static int last_event;
- int t, dt;
-
- t = timer0_reload_read() - timer0_value_read(); // TODO: atomic read
- dt = t - last_event;
- if(dt < 0)
- dt += timer0_reload_read();
- if((dt > period) || (dt < 0)) {
- last_event = t;
- return 1;
- } else
- return 0;
-}
+static int dvisamplerX_last_event;
void dvisamplerX_service(void)
{
if(dvisamplerX_locked) {
if(dvisamplerX_clocking_locked_read()) {
- if(elapsed(identifier_frequency_read())) {
+ if(elapsed(&dvisamplerX_last_event, identifier_frequency_read())) {
dvisamplerX_adjust_phase();
dvisamplerX_print_status();
}
dvisamplerX_print_status();
dvisamplerX_locked = 1;
} else {
- if(elapsed(identifier_frequency_read()/4)) {
+ if(elapsed(&dvisamplerX_last_event, identifier_frequency_read()/4)) {
dvisamplerX_clocking_pll_reset_write(1);
- while(!elapsed(identifier_frequency_read()/16));
+ while(!elapsed(&dvisamplerX_last_event, identifier_frequency_read()/16));
dvisamplerX_clocking_pll_reset_write(0);
}
}
#include <hw/flags.h>
#include <console.h>
+#include "time.h"
#include "dvisampler0.h"
#include "dvisampler1.h"
-int main(void)
+static int scale_pot(int raw, int range)
+{
+ int pot_min = 54000;
+ int pot_max = 105400;
+ int scaled;
+
+ scaled = range*(raw - pot_min)/(pot_max - pot_min);
+ if(scaled < 0)
+ scaled = 0;
+ if(scaled > range)
+ scaled = range;
+ return scaled;
+}
+
+static void pots_service(void)
+{
+ static int last_event;
+ int blackout;
+ int crossfade;
+
+ if(elapsed(&last_event, identifier_frequency_read()/32)) {
+ pots_start_busy_write(1);
+ while(pots_start_busy_read());
+ blackout = scale_pot(pots_res0_read(), 256);
+ crossfade = scale_pot(pots_res1_read(), 255);
+
+ fb_blender_f0_write(crossfade*blackout >> 8);
+ fb_blender_f1_write((255-crossfade)*blackout >> 8);
+ }
+}
+
+static void fb_service(void)
{
int c;
+ if(readchar_nonblock()) {
+ c = readchar();
+ if(c == '1') {
+ fb_enable_write(1);
+ printf("Framebuffer is ON\n");
+ } else if(c == '0') {
+ fb_enable_write(0);
+ printf("Framebuffer is OFF\n");
+ }
+ }
+}
+
+int main(void)
+{
irq_setmask(0);
irq_setie(1);
uart_init();
puts("Minimal video mixer software built "__DATE__" "__TIME__"\n");
- timer0_reload_write(2*identifier_frequency_read());
- timer0_en_write(1);
-
+ time_init();
dvisampler0_init_video();
dvisampler1_init_video();
fb_enable_write(1);
- fb_blender_f0_write(127);
- fb_blender_f1_write(127);
+
while(1) {
dvisampler0_service();
dvisampler1_service();
- if(readchar_nonblock()) {
- c = readchar();
- if(c == '1') {
- fb_enable_write(1);
- printf("Framebuffer is ON\n");
- } else if(c == '0') {
- fb_enable_write(0);
- printf("Framebuffer is OFF\n");
- }
- }
+ pots_service();
+ fb_service();
}
return 0;
--- /dev/null
+#include <hw/csr.h>
+
+#include "time.h"
+
+void time_init(void)
+{
+ timer0_reload_write(2*identifier_frequency_read());
+ timer0_en_write(1);
+}
+
+int elapsed(int *last_event, int period)
+{
+ int t, dt;
+
+ t = timer0_reload_read() - timer0_value_read(); // TODO: atomic read
+ dt = t - *last_event;
+ if(dt < 0)
+ dt += timer0_reload_read();
+ if((dt > period) || (dt < 0)) {
+ *last_event = t;
+ return 1;
+ } else
+ return 0;
+}
--- /dev/null
+#ifndef __TIME_H
+#define __TIME_H
+
+void time_init(void);
+int elapsed(int *last_event, int period);
+
+#endif /* __TIME_H */