Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: m-labs/misoc
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: d685ed21fc45
Choose a base ref
...
head repository: m-labs/misoc
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: c6d553e4e4ff
Choose a head ref
  • 3 commits
  • 4 files changed
  • 1 contributor

Commits on May 9, 2013

  1. dvisampler/dma: fix interrupt generation

    Sebastien Bourdeauducq committed May 9, 2013
    Copy the full SHA
    2df4ff0 View commit details
  2. dvisampler/dma: reverse slot allocation order

    Sebastien Bourdeauducq committed May 9, 2013
    Copy the full SHA
    fe87221 View commit details
  3. software/videomixer: interrupt-driven video passthrough

    Sebastien Bourdeauducq committed May 9, 2013
    Copy the full SHA
    c6d553e View commit details
Showing with 77 additions and 31 deletions.
  1. +2 −2 milkymist/dvisampler/dma.py
  2. +4 −0 software/include/hw/flags.h
  3. +4 −0 software/videomixer/isr.c
  4. +67 −29 software/videomixer/main.c
4 changes: 2 additions & 2 deletions milkymist/dvisampler/dma.py
Original file line number Diff line number Diff line change
@@ -31,7 +31,7 @@ def __init__(self, addr_bits, alignment_bits):

class _SlotArray(Module, AutoCSR):
def __init__(self, nslots, addr_bits, alignment_bits):
self.ev = EventManager()
self.submodules.ev = EventManager()
self.address = Signal(addr_bits)
self.address_valid = Signal()
self.address_done = Signal()
@@ -46,7 +46,7 @@ def __init__(self, nslots, addr_bits, alignment_bits):

change_slot = Signal()
current_slot = Signal(max=nslots)
self.sync += If(change_slot, [If(slot.address_valid, current_slot.eq(n)) for n, slot in enumerate(slots)])
self.sync += If(change_slot, [If(slot.address_valid, current_slot.eq(n)) for n, slot in reversed(list(enumerate(slots)))])
self.comb += change_slot.eq(~self.address_valid | self.address_done)

self.comb += [
4 changes: 4 additions & 0 deletions software/include/hw/flags.h
Original file line number Diff line number Diff line change
@@ -30,4 +30,8 @@
#define DVISAMPLER_DELAY_INC 0x4
#define DVISAMPLER_DELAY_DEC 0x8

#define DVISAMPLER_SLOT_EMPTY 0
#define DVISAMPLER_SLOT_LOADED 1
#define DVISAMPLER_SLOT_PENDING 2

#endif /* __HW_FLAGS_H */
4 changes: 4 additions & 0 deletions software/videomixer/isr.c
Original file line number Diff line number Diff line change
@@ -2,6 +2,8 @@
#include <irq.h>
#include <uart.h>

void dvisampler0_isr(void); // FIXME

void isr(void);
void isr(void)
{
@@ -11,4 +13,6 @@ void isr(void)

if(irqs & (1 << UART_INTERRUPT))
uart_isr();
if(irqs & (1 << DVISAMPLER0_INTERRUPT))
dvisampler0_isr();
}
96 changes: 67 additions & 29 deletions software/videomixer/main.c
Original file line number Diff line number Diff line change
@@ -7,12 +7,11 @@
#include <hw/csr.h>
#include <hw/flags.h>

static int d0, d1, d2;
static unsigned int framebuffer[640*480] __attribute__((aligned(16)));
static int dvisampler0_d0, dvisampler0_d1, dvisampler0_d2;

static void print_status(void)
{
printf("Ph: %4d %4d %4d // %d%d%d [%d %d %d] // %d // %dx%d\n", d0, d1, d2,
printf("dvisampler0 ph: %4d %4d %4d // %d%d%d [%d %d %d] // %d // %dx%d\n", dvisampler0_d0, dvisampler0_d1, dvisampler0_d2,
dvisampler0_data0_charsync_char_synced_read(),
dvisampler0_data1_charsync_char_synced_read(),
dvisampler0_data2_charsync_char_synced_read(),
@@ -24,17 +23,6 @@ static void print_status(void)
dvisampler0_resdetection_vres_read());
}

static void capture_fb(void)
{
dvisampler0_dma_frame_size_write(sizeof(framebuffer));
dvisampler0_dma_slot0_address_write((unsigned int)framebuffer);
dvisampler0_dma_slot0_status_write(1);

printf("waiting for DMA...");
while(dvisampler0_dma_slot0_status_read() != 2);
printf("done\n");
}

static void calibrate_delays(void)
{
dvisampler0_data0_cap_dly_ctl_write(DVISAMPLER_DELAY_CAL);
@@ -49,7 +37,7 @@ static void calibrate_delays(void)
dvisampler0_data0_cap_phase_reset_write(1);
dvisampler0_data1_cap_phase_reset_write(1);
dvisampler0_data2_cap_phase_reset_write(1);
d0 = d1 = d2 = 0;
dvisampler0_d0 = dvisampler0_d1 = dvisampler0_d2 = 0;
printf("Delays calibrated\n");
}

@@ -58,58 +46,110 @@ static void adjust_phase(void)
switch(dvisampler0_data0_cap_phase_read()) {
case DVISAMPLER_TOO_LATE:
dvisampler0_data0_cap_dly_ctl_write(DVISAMPLER_DELAY_DEC);
d0--;
dvisampler0_d0--;
dvisampler0_data0_cap_phase_reset_write(1);
break;
case DVISAMPLER_TOO_EARLY:
dvisampler0_data0_cap_dly_ctl_write(DVISAMPLER_DELAY_INC);
d0++;
dvisampler0_d0++;
dvisampler0_data0_cap_phase_reset_write(1);
break;
}
switch(dvisampler0_data1_cap_phase_read()) {
case DVISAMPLER_TOO_LATE:
dvisampler0_data1_cap_dly_ctl_write(DVISAMPLER_DELAY_DEC);
d1--;
dvisampler0_d1--;
dvisampler0_data1_cap_phase_reset_write(1);
break;
case DVISAMPLER_TOO_EARLY:
dvisampler0_data1_cap_dly_ctl_write(DVISAMPLER_DELAY_INC);
d1++;
dvisampler0_d1++;
dvisampler0_data1_cap_phase_reset_write(1);
break;
}
switch(dvisampler0_data2_cap_phase_read()) {
case DVISAMPLER_TOO_LATE:
dvisampler0_data2_cap_dly_ctl_write(DVISAMPLER_DELAY_DEC);
d2--;
dvisampler0_d2--;
dvisampler0_data2_cap_phase_reset_write(1);
break;
case DVISAMPLER_TOO_EARLY:
dvisampler0_data2_cap_dly_ctl_write(DVISAMPLER_DELAY_INC);
d2++;
dvisampler0_d2++;
dvisampler0_data2_cap_phase_reset_write(1);
break;
}
}

static int init_phase(void)
{
int od0, od1, od2;
int o_d0, o_d1, o_d2;
int i, j;

for(i=0;i<100;i++) {
od0 = d0;
od1 = d1;
od2 = d2;
o_d0 = dvisampler0_d0;
o_d1 = dvisampler0_d1;
o_d2 = dvisampler0_d2;
for(j=0;j<1000;j++)
adjust_phase();
if((abs(d0 - od0) < 4) && (abs(d1 - od1) < 4) && (abs(d2 - od2) < 4))
if((abs(dvisampler0_d0 - o_d0) < 4) && (abs(dvisampler0_d1 - o_d1) < 4) && (abs(dvisampler0_d2 - o_d2) < 4))
return 1;
}
return 0;
}

#define FRAMEBUFFER_COUNT 4
#define FRAMEBUFFER_MASK (FRAMEBUFFER_COUNT - 1)

static unsigned int dvisampler0_framebuffers[FRAMEBUFFER_COUNT][640*480] __attribute__((aligned(16)));
static int dvisampler0_fb_slot_indexes[2];
static int dvisampler0_next_fb_index;

static void dvisampler0_init_video(void)
{
unsigned int mask;

dvisampler0_dma_ev_pending_write(dvisampler0_dma_ev_pending_read());
dvisampler0_dma_ev_enable_write(0x3);
mask = irq_getmask();
mask |= 1 << DVISAMPLER0_INTERRUPT;
irq_setmask(mask);

dvisampler0_dma_frame_size_write(sizeof(dvisampler0_framebuffers[0]));
dvisampler0_fb_slot_indexes[0] = 0;
dvisampler0_dma_slot0_address_write((unsigned int)dvisampler0_framebuffers[0]);
dvisampler0_dma_slot0_status_write(DVISAMPLER_SLOT_LOADED);
dvisampler0_fb_slot_indexes[1] = 1;
dvisampler0_dma_slot1_address_write((unsigned int)dvisampler0_framebuffers[1]);
dvisampler0_dma_slot1_status_write(DVISAMPLER_SLOT_LOADED);
dvisampler0_next_fb_index = 2;

fb_base_write((unsigned int)dvisampler0_framebuffers[0]);
}

void dvisampler0_isr(void)
{
int fb_index = -1;

if(dvisampler0_dma_slot0_status_read() == DVISAMPLER_SLOT_PENDING) {
fb_index = dvisampler0_fb_slot_indexes[0];
dvisampler0_fb_slot_indexes[0] = dvisampler0_next_fb_index;
dvisampler0_dma_slot0_address_write((unsigned int)dvisampler0_framebuffers[dvisampler0_next_fb_index]);
dvisampler0_dma_slot0_status_write(DVISAMPLER_SLOT_LOADED);
dvisampler0_next_fb_index = (dvisampler0_next_fb_index + 1) & FRAMEBUFFER_MASK;
}
if(dvisampler0_dma_slot1_status_read() == DVISAMPLER_SLOT_PENDING) {
fb_index = dvisampler0_fb_slot_indexes[1];
dvisampler0_fb_slot_indexes[1] = dvisampler0_next_fb_index;
dvisampler0_dma_slot1_address_write((unsigned int)dvisampler0_framebuffers[dvisampler0_next_fb_index]);
dvisampler0_dma_slot1_status_write(DVISAMPLER_SLOT_LOADED);
dvisampler0_next_fb_index = (dvisampler0_next_fb_index + 1) & FRAMEBUFFER_MASK;
}

if(fb_index != -1)
fb_base_write((unsigned int)dvisampler0_framebuffers[fb_index]);
}

static void vmix(void)
{
unsigned int counter;
@@ -132,8 +172,6 @@ static void vmix(void)
adjust_phase();
counter = 0;
}
if(readchar_nonblock() && (readchar() == 'c'))
capture_fb();
}
printf("PLL unlocked\n");
}
@@ -147,7 +185,7 @@ int main(void)

puts("Minimal video mixer software built "__DATE__" "__TIME__"\n");

fb_base_write((unsigned int)framebuffer);
dvisampler0_init_video();
fb_enable_write(1);
vmix();