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: c6d553e4e4ff
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: 546aa76aef8e
Choose a head ref
  • 2 commits
  • 6 files changed
  • 1 contributor

Commits on May 9, 2013

  1. dvisampler/dma: better 8:8:8 -> 10:10:10 conversion

    Sebastien Bourdeauducq committed May 9, 2013
    Copy the full SHA
    06064d3 View commit details
  2. software/dvimixer: support two channels

    Sebastien Bourdeauducq committed May 9, 2013
    Copy the full SHA
    546aa76 View commit details
Showing with 230 additions and 176 deletions.
  1. +3 −3 milkymist/dvisampler/dma.py
  2. +26 −1 software/videomixer/Makefile
  3. +182 −0 software/videomixer/dvisamplerX.c
  4. +12 −0 software/videomixer/dvisamplerX.h
  5. +4 −1 software/videomixer/isr.c
  6. +3 −171 software/videomixer/main.c
6 changes: 3 additions & 3 deletions milkymist/dvisampler/dma.py
Original file line number Diff line number Diff line change
@@ -98,9 +98,9 @@ def __init__(self, asmiport, nslots):
encoded_pixel = Signal(32)
self.comb += [
encoded_pixel.eq(Cat(
Replicate(0, 2), self.frame.payload.b,
Replicate(0, 2), self.frame.payload.g,
Replicate(0, 2), self.frame.payload.r))
self.frame.payload.b[6:], self.frame.payload.b,
self.frame.payload.g[6:], self.frame.payload.g,
self.frame.payload.r[6:], self.frame.payload.r))
]
pack_factor = bus_dw//32
assert(pack_factor & (pack_factor - 1) == 0) # only support powers of 2
27 changes: 26 additions & 1 deletion software/videomixer/Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
M2DIR=../..
include $(M2DIR)/software/common.mak

OBJECTS=crt0.o isr.o main.o
OBJECTS=crt0.o isr.o dvisampler0.o dvisampler1.o main.o

all: videomixer.bin

@@ -30,6 +30,30 @@ main.o: main.c
%.o: %.S
$(assemble)

define gen0
@echo " GEN " $@
@sed -e "s/dvisamplerX/dvisampler0/g;s/DVISAMPLERX/DVISAMPLER0/g" $< > $@
endef

define gen1
@echo " GEN " $@
@sed -e "s/dvisamplerX/dvisampler1/g;s/DVISAMPLERX/DVISAMPLER1/g" $< > $@
endef

dvisampler0.c: dvisamplerX.c
$(gen0)
dvisampler0.h: dvisamplerX.h
$(gen0)
dvisampler1.c: dvisamplerX.c
$(gen1)
dvisampler1.h: dvisamplerX.h
$(gen1)

isr.o: dvisampler0.h dvisampler1.h
main.o: dvisampler0.h dvisampler1.h
dvisampler0.o: dvisampler0.h
dvisampler1.o: dvisampler1.h

libs:
make -C $(M2DIR)/software/libcompiler-rt
make -C $(M2DIR)/software/libbase
@@ -40,5 +64,6 @@ load: videomixer.bin

clean:
rm -f $(OBJECTS) $(OBJECTS:.o=.d) videomixer.elf videomixer.bin .*~ *~
rm -f dvisampler0.h dvisampler0.c dvisampler1.h dvisampler1.c

.PHONY: main.o clean libs load
182 changes: 182 additions & 0 deletions software/videomixer/dvisamplerX.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
#include <stdio.h>
#include <stdlib.h>

#include <irq.h>
#include <uart.h>
#include <hw/csr.h>
#include <hw/flags.h>

#include "dvisamplerX.h"

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

static unsigned int dvisamplerX_framebuffers[FRAMEBUFFER_COUNT][640*480] __attribute__((aligned(16)));
static int dvisamplerX_fb_slot_indexes[2];
static int dvisamplerX_next_fb_index;

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

if(dvisamplerX_dma_slot0_status_read() == DVISAMPLER_SLOT_PENDING) {
fb_index = dvisamplerX_fb_slot_indexes[0];
dvisamplerX_fb_slot_indexes[0] = dvisamplerX_next_fb_index;
dvisamplerX_dma_slot0_address_write((unsigned int)dvisamplerX_framebuffers[dvisamplerX_next_fb_index]);
dvisamplerX_dma_slot0_status_write(DVISAMPLER_SLOT_LOADED);
dvisamplerX_next_fb_index = (dvisamplerX_next_fb_index + 1) & FRAMEBUFFER_MASK;
}
if(dvisamplerX_dma_slot1_status_read() == DVISAMPLER_SLOT_PENDING) {
fb_index = dvisamplerX_fb_slot_indexes[1];
dvisamplerX_fb_slot_indexes[1] = dvisamplerX_next_fb_index;
dvisamplerX_dma_slot1_address_write((unsigned int)dvisamplerX_framebuffers[dvisamplerX_next_fb_index]);
dvisamplerX_dma_slot1_status_write(DVISAMPLER_SLOT_LOADED);
dvisamplerX_next_fb_index = (dvisamplerX_next_fb_index + 1) & FRAMEBUFFER_MASK;
}

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

void dvisamplerX_init_video(void)
{
unsigned int mask;

dvisamplerX_dma_ev_pending_write(dvisamplerX_dma_ev_pending_read());
dvisamplerX_dma_ev_enable_write(0x3);
mask = irq_getmask();
mask |= 1 << DVISAMPLERX_INTERRUPT;
irq_setmask(mask);

dvisamplerX_dma_frame_size_write(sizeof(dvisamplerX_framebuffers[0]));
dvisamplerX_fb_slot_indexes[0] = 0;
dvisamplerX_dma_slot0_address_write((unsigned int)dvisamplerX_framebuffers[0]);
dvisamplerX_dma_slot0_status_write(DVISAMPLER_SLOT_LOADED);
dvisamplerX_fb_slot_indexes[1] = 1;
dvisamplerX_dma_slot1_address_write((unsigned int)dvisamplerX_framebuffers[1]);
dvisamplerX_dma_slot1_status_write(DVISAMPLER_SLOT_LOADED);
dvisamplerX_next_fb_index = 2;

fb_base_write((unsigned int)dvisamplerX_framebuffers[3]);
}

static int dvisamplerX_d0, dvisamplerX_d1, dvisamplerX_d2;

void dvisamplerX_print_status(void)
{
printf("dvisamplerX ph:%4d %4d %4d // charsync:%d%d%d [%d %d %d] // chansync:%d // res:%dx%d\n",
dvisamplerX_d0, dvisamplerX_d1, dvisamplerX_d2,
dvisamplerX_data0_charsync_char_synced_read(),
dvisamplerX_data1_charsync_char_synced_read(),
dvisamplerX_data2_charsync_char_synced_read(),
dvisamplerX_data0_charsync_ctl_pos_read(),
dvisamplerX_data1_charsync_ctl_pos_read(),
dvisamplerX_data2_charsync_ctl_pos_read(),
dvisamplerX_chansync_channels_synced_read(),
dvisamplerX_resdetection_hres_read(),
dvisamplerX_resdetection_vres_read());
}

void dvisamplerX_calibrate_delays(void)
{
dvisamplerX_data0_cap_dly_ctl_write(DVISAMPLER_DELAY_CAL);
dvisamplerX_data1_cap_dly_ctl_write(DVISAMPLER_DELAY_CAL);
dvisamplerX_data2_cap_dly_ctl_write(DVISAMPLER_DELAY_CAL);
while(dvisamplerX_data0_cap_dly_busy_read()
|| dvisamplerX_data1_cap_dly_busy_read()
|| dvisamplerX_data2_cap_dly_busy_read());
dvisamplerX_data0_cap_dly_ctl_write(DVISAMPLER_DELAY_RST);
dvisamplerX_data1_cap_dly_ctl_write(DVISAMPLER_DELAY_RST);
dvisamplerX_data2_cap_dly_ctl_write(DVISAMPLER_DELAY_RST);
dvisamplerX_data0_cap_phase_reset_write(1);
dvisamplerX_data1_cap_phase_reset_write(1);
dvisamplerX_data2_cap_phase_reset_write(1);
dvisamplerX_d0 = dvisamplerX_d1 = dvisamplerX_d2 = 0;
}

void dvisamplerX_adjust_phase(void)
{
switch(dvisamplerX_data0_cap_phase_read()) {
case DVISAMPLER_TOO_LATE:
dvisamplerX_data0_cap_dly_ctl_write(DVISAMPLER_DELAY_DEC);
dvisamplerX_d0--;
dvisamplerX_data0_cap_phase_reset_write(1);
break;
case DVISAMPLER_TOO_EARLY:
dvisamplerX_data0_cap_dly_ctl_write(DVISAMPLER_DELAY_INC);
dvisamplerX_d0++;
dvisamplerX_data0_cap_phase_reset_write(1);
break;
}
switch(dvisamplerX_data1_cap_phase_read()) {
case DVISAMPLER_TOO_LATE:
dvisamplerX_data1_cap_dly_ctl_write(DVISAMPLER_DELAY_DEC);
dvisamplerX_d1--;
dvisamplerX_data1_cap_phase_reset_write(1);
break;
case DVISAMPLER_TOO_EARLY:
dvisamplerX_data1_cap_dly_ctl_write(DVISAMPLER_DELAY_INC);
dvisamplerX_d1++;
dvisamplerX_data1_cap_phase_reset_write(1);
break;
}
switch(dvisamplerX_data2_cap_phase_read()) {
case DVISAMPLER_TOO_LATE:
dvisamplerX_data2_cap_dly_ctl_write(DVISAMPLER_DELAY_DEC);
dvisamplerX_d2--;
dvisamplerX_data2_cap_phase_reset_write(1);
break;
case DVISAMPLER_TOO_EARLY:
dvisamplerX_data2_cap_dly_ctl_write(DVISAMPLER_DELAY_INC);
dvisamplerX_d2++;
dvisamplerX_data2_cap_phase_reset_write(1);
break;
}
}

int dvisamplerX_init_phase(void)
{
int o_d0, o_d1, o_d2;
int i, j;

for(i=0;i<100;i++) {
o_d0 = dvisamplerX_d0;
o_d1 = dvisamplerX_d1;
o_d2 = dvisamplerX_d2;
for(j=0;j<1000;j++)
dvisamplerX_adjust_phase();
if((abs(dvisamplerX_d0 - o_d0) < 4) && (abs(dvisamplerX_d1 - o_d1) < 4) && (abs(dvisamplerX_d2 - o_d2) < 4))
return 1;
}
return 0;
}

static int dvisamplerX_locked;

void dvisamplerX_service(void)
{
int ret;

if(dvisamplerX_locked) {
if(dvisamplerX_clocking_locked_read()) {
dvisamplerX_adjust_phase();
dvisamplerX_print_status();
} else {
printf("dvisamplerX: lost PLL lock\n");
dvisamplerX_locked = 0;
}
} else {
if(dvisamplerX_clocking_locked_read()) {
printf("dvisamplerX: PLL locked\n");
dvisamplerX_calibrate_delays();
printf("dvisamplerX: delays calibrated\n");
ret = dvisamplerX_init_phase();
if(ret)
printf("dvisamplerX: phase init OK\n");
else
printf("dvisamplerX: phase did not settle\n");
dvisamplerX_print_status();
dvisamplerX_locked = 1;
}
}
}
12 changes: 12 additions & 0 deletions software/videomixer/dvisamplerX.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#ifndef __DVISAMPLERX_H
#define __DVISAMPLERX_H

void dvisamplerX_isr(void);
void dvisamplerX_init_video(void);
void dvisamplerX_print_status(void);
void dvisamplerX_calibrate_delays(void);
void dvisamplerX_adjust_phase(void);
int dvisamplerX_init_phase(void);
void dvisamplerX_service(void);

#endif
5 changes: 4 additions & 1 deletion software/videomixer/isr.c
Original file line number Diff line number Diff line change
@@ -2,7 +2,8 @@
#include <irq.h>
#include <uart.h>

void dvisampler0_isr(void); // FIXME
#include "dvisampler0.h"
#include "dvisampler1.h"

void isr(void);
void isr(void)
@@ -15,4 +16,6 @@ void isr(void)
uart_isr();
if(irqs & (1 << DVISAMPLER0_INTERRUPT))
dvisampler0_isr();
if(irqs & (1 << DVISAMPLER1_INTERRUPT))
dvisampler1_isr();
}
Loading