Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rebase camera interface demo #3

Merged
merged 4 commits into from Oct 30, 2018
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

@@ -2,21 +2,44 @@ CTRLSOC_DEV =
MLACCEL_DEV =
SEED = 1234

CAMERA_RTL = \
camera/phy/dphy_iserdes.v \
camera/phy/byte_aligner.v \
camera/phy/word_combiner.v \
camera/csi/header_ecc.v \
camera/csi/rx_packet_handler.v \
camera/link/csi_rx_ice40.v \
camera/misc/downsample.v \
camera/cameraif.v

SPI_RTL = \
spiflash.v

SOC_RTL = \
ctrlsoc.v \
picorv32.v

ML_RTL = \
../rtl/top.v \
../rtl/sequencer.v \
../rtl/compute.v \
../rtl/memory.v

#####################################################################

testbench.vcd: testbench flashinit.hex ctrlsoc_fw.hex
vvp -N testbench

testbench: testbench.v spiflash.v ctrlsoc.v picorv32.v ../rtl/top.v ../rtl/sequencer.v ../rtl/compute.v ../rtl/memory.v
iverilog -s testbench -o $@ testbench.v spiflash.v ctrlsoc.v picorv32.v ../rtl/top.v ../rtl/sequencer.v ../rtl/compute.v ../rtl/memory.v $(shell yosys-config --datdir/ice40/cells_sim.v)
testbench: testbench.v $(SPI_RTL) $(SOC_RTL) $(ML_RTL) $(CAMERA_RTL)
iverilog -s testbench -o $@ $^ $(shell yosys-config --datdir/ice40/cells_sim.v)

flashinit.hex: flashinit.py
python3 flashinit.py

#####################################################################

ctrlsoc.json: ctrlsoc.v picorv32.v flashinit.hex
yosys -ql ctrlsoc.log -p 'synth_ice40 -top ctrlsoc -json ctrlsoc.json' ctrlsoc.v picorv32.v
ctrlsoc.json: $(SOC_RTL) $(CAMERA_RTL) flashinit.hex
yosys -ql ctrlsoc.log -p 'synth_ice40 -top ctrlsoc -json ctrlsoc.json' $(filter %.v, $^)

ctrlsoc.asc: ctrlsoc.pcf ctrlsoc.json
nextpnr-ice40 --freq 13 --up5k --asc ctrlsoc.asc --pcf ctrlsoc.pcf --json ctrlsoc.json
@@ -25,8 +48,8 @@ ctrlsoc.bin: ctrlsoc.asc
icetime -d up5k -c 12 -mtr ctrlsoc.rpt ctrlsoc.asc
icepack ctrlsoc.asc ctrlsoc.bin

ctrlsoc_fw.elf: sections.lds start.S firmware.c demodat.inc
riscv32-unknown-elf-gcc -O1 -Wall -Wextra -march=rv32i -Wl,-Bstatic,-T,sections.lds,--strip-debug -ffreestanding -nostdlib -o ctrlsoc_fw.elf start.S firmware.c
ctrlsoc_fw.elf: sections.lds start.S firmware.c demodat.inc camera/camera.c
riscv32-unknown-elf-gcc -O1 -Wall -Wextra -march=rv32i -Wl,-Bstatic,-T,sections.lds,--strip-debug -ffreestanding -nostdlib -o ctrlsoc_fw.elf start.S firmware.c camera/camera.c

ctrlsoc_fw.hex: ctrlsoc_fw.elf
riscv32-unknown-elf-objcopy -O verilog ctrlsoc_fw.elf ctrlsoc_fw.hex
@@ -57,8 +80,8 @@ clean_ctrlsoc:
#####################################################################

mlaccel.blif: mlaccel.json
mlaccel.json: ../rtl/top.v ../rtl/sequencer.v ../rtl/compute.v ../rtl/memory.v
yosys -ql mlaccel.log -p 'synth_ice40 -top mlaccel_top -json mlaccel.json -blif mlaccel.blif' ../rtl/top.v ../rtl/sequencer.v ../rtl/compute.v ../rtl/memory.v
mlaccel.json: $(ML_RTL)
yosys -ql mlaccel.log -p 'synth_ice40 -top mlaccel_top -json mlaccel.json -blif mlaccel.blif' $(ML_RTL)

mlaccel.asc: mlaccel.pcf mlaccel.json
nextpnr-ice40 --seed $(SEED) --freq 25 --up5k --asc mlaccel.asc --pcf mlaccel.pcf --json mlaccel.json
@@ -0,0 +1,168 @@
/*
* Copyright (C) 2018 David Shah <david@symbioticeda.com>
*
* Permission to use, copy, modify, and/or 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 "camera.h"
#define CAMERA_BASE 0x03000000

#define reg_camera_i2c (*(volatile uint32_t*)CAMERA_BASE)
#define reg_camera_fb ((volatile uint8_t*)(CAMERA_BASE + 0x8000))

static void i2c_delay() {
for (volatile int i = 0; i < 10; i++)
;
}

static void set_i2c_io(uint8_t sda, uint8_t scl) {
reg_camera_i2c = ((scl & 0x1) << 1) | (sda & 0x1);
i2c_delay();
}

static void i2c_start() {
set_i2c_io(1, 1);
set_i2c_io(0, 1);
set_i2c_io(0, 0);
}

static void i2c_send(uint8_t data) {
for (int i = 7; i >= 0; i--) {
uint8_t bit = (data >> i) & 0x1;
set_i2c_io(bit, 0);
set_i2c_io(bit, 1);
set_i2c_io(bit, 0);
}
set_i2c_io(1, 0);
set_i2c_io(1, 1);
set_i2c_io(1, 0);
}

static void i2c_stop() {
set_i2c_io(0, 0);
set_i2c_io(0, 1);
set_i2c_io(1, 1);
}

void camera_i2c_write(uint16_t address, uint8_t data) {
i2c_start();
i2c_send(0x10 << 1);
i2c_send((address >> 8) & 0xFF);
i2c_send(address & 0xFF);
i2c_send(data);
i2c_stop();
}

const int framelength = 666;
const int linelength = 3448;

void camera_init() {
// Based on "Preview Setting" from a Linux driver
camera_i2c_write(0x0100, 0x00); //standby mode
camera_i2c_write(0x30EB, 0x05); //mfg specific access begin
camera_i2c_write(0x30EB, 0x0C); //
camera_i2c_write(0x300A, 0xFF); //
camera_i2c_write(0x300B, 0xFF); //
camera_i2c_write(0x30EB, 0x05); //
camera_i2c_write(0x30EB, 0x09); //mfg specific access end
camera_i2c_write(0x0114, 0x01); //CSI_LANE_MODE: 2-lane
camera_i2c_write(0x0128, 0x00); //DPHY_CTRL: auto mode (?)
camera_i2c_write(0x012A, 0x18); //EXCK_FREQ[15:8] = 24MHz
camera_i2c_write(0x012B, 0x00); //EXCK_FREQ[7:0]
camera_i2c_write(0x0160, ((framelength >> 8) & 0xFF)); //framelength
camera_i2c_write(0x0161, (framelength & 0xFF));
camera_i2c_write(0x0162, ((linelength >> 8) & 0xFF));
camera_i2c_write(0x0163, (linelength & 0xFF));
camera_i2c_write(0x0164, 0x00); //X_ADD_STA_A[11:8]
camera_i2c_write(0x0165, 0x00); //X_ADD_STA_A[7:0]
camera_i2c_write(0x0166, 0x0A); //X_ADD_END_A[11:8]
camera_i2c_write(0x0167, 0x00); //X_ADD_END_A[7:0]
camera_i2c_write(0x0168, 0x00); //Y_ADD_STA_A[11:8]
camera_i2c_write(0x0169, 0x00); //Y_ADD_STA_A[7:0]
camera_i2c_write(0x016A, 0x07); //Y_ADD_END_A[11:8]
camera_i2c_write(0x016B, 0x80); //Y_ADD_END_A[7:0]
camera_i2c_write(0x016C, 0x02); //x_output_size[11:8] = 640
camera_i2c_write(0x016D, 0x80); //x_output_size[7:0]
camera_i2c_write(0x016E, 0x01); //y_output_size[11:8] = 480
camera_i2c_write(0x016F, 0xE0); //y_output_size[7:0]
camera_i2c_write(0x0170, 0x01); //X_ODD_INC_A
camera_i2c_write(0x0171, 0x01); //Y_ODD_INC_A
camera_i2c_write(0x0174, 0x02); //BINNING_MODE_H_A = x4-binning
camera_i2c_write(0x0175, 0x02); //BINNING_MODE_V_A = x4-binning
camera_i2c_write(0x018C, 0x08); //CSI_DATA_FORMAT_A[15:8]
camera_i2c_write(0x018D, 0x08); //CSI_DATA_FORMAT_A[7:0]
camera_i2c_write(0x0301, 0x08); //VTPXCK_DIV
camera_i2c_write(0x0303, 0x01); //VTSYCK_DIV
camera_i2c_write(0x0304, 0x03); //PREPLLCK_VT_DIV
camera_i2c_write(0x0305, 0x03); //PREPLLCK_OP_DIV
camera_i2c_write(0x0306, 0x00); //PLL_VT_MPY[10:8]
camera_i2c_write(0x0307, 0x14); //PLL_VT_MPY[7:0]
camera_i2c_write(0x0309, 0x08); //OPPXCK_DIV
camera_i2c_write(0x030B, 0x02); //OPSYCK_DIV
camera_i2c_write(0x030C, 0x00); //PLL_OP_MPY[10:8]
camera_i2c_write(0x030D, 0x0A); //PLL_OP_MPY[7:0]
camera_i2c_write(0x455E, 0x00); //??
camera_i2c_write(0x471E, 0x4B); //??
camera_i2c_write(0x4767, 0x0F); //??
camera_i2c_write(0x4750, 0x14); //??
camera_i2c_write(0x4540, 0x00); //??
camera_i2c_write(0x47B4, 0x14); //??
camera_i2c_write(0x4713, 0x30); //??
camera_i2c_write(0x478B, 0x10); //??
camera_i2c_write(0x478F, 0x10); //??
camera_i2c_write(0x4793, 0x10); //??
camera_i2c_write(0x4797, 0x0E); //??
camera_i2c_write(0x479B, 0x0E); //??

//camera_i2c_write(0x0157, 232); // ANA_GAIN_GLOBAL_A
//camera_i2c_write(0x0257, 232); // ANA_GAIN_GLOBAL_B


//camera_i2c_write(0x0600, 0x00); // Test pattern: disable
//camera_i2c_write(0x0601, 0x00); // Test pattern: disable

#if 0
camera_i2c_write(0x0600, 0x00); // Test pattern: solid colour
camera_i2c_write(0x0601, 0x01); //

camera_i2c_write(0x0602, 0x02); // Test pattern: red
camera_i2c_write(0x0603, 0xAA); //

camera_i2c_write(0x0604, 0x02); // Test pattern: greenR
camera_i2c_write(0x0605, 0xAA); //

camera_i2c_write(0x0606, 0x02); // Test pattern: blue
camera_i2c_write(0x0607, 0xAA); //

camera_i2c_write(0x0608, 0x02); // Test pattern: greenB
camera_i2c_write(0x0609, 0xAA); //


camera_i2c_write(0x0624, 0x0A); // Test pattern width
camera_i2c_write(0x0625, 0x00); //

camera_i2c_write(0x0626, 0x07); // Test pattern height
camera_i2c_write(0x0627, 0x80); //


#endif

camera_i2c_write(0x0100, 0x01);
}

void acquire_image(uint8_t *buffer) {
for (int y = 0; y < 30; y++)
for (int x = 0; x < 40; x++)
*(buffer++) = reg_camera_fb[((y << 6) | x) << 2];
}
@@ -0,0 +1,33 @@
/*
* Copyright (C) 2018 David Shah <david@symbioticeda.com>
*
* Permission to use, copy, modify, and/or 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.
*
*/


#ifndef CAMERA_H
#define CAMERA_H

#include <stdint.h>

// Write to camera register
void camera_i2c_write(uint16_t address, uint8_t data);

// Init camera with default config
void camera_init();

// Copy 40x30 to buffer
void acquire_image(uint8_t *buffer);

#endif
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2018 Clifford Wolf <clifford@symbioticeda.com>
* Copyright (C) 2018 David Shah <david@symbioticeda.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -114,20 +114,42 @@ module cameraif(
wire [1:0] i2c_din;
reg [1:0] i2c_gpio;
reg [1:0] i2c_read;
reg i2c_read_last;

SB_IO #(
.PIN_TYPE(6'b 1010_01),
.PULLUP(1'b 1)
) scl_buf (
.PACKAGE_PIN(cam_sda),
.OUTPUT_ENABLE(!i2c_gpio[0]),
.D_OUT_0(1'b0),
.D_IN_0(i2c_din[0])
);

SB_IO #(
.PIN_TYPE(6'b 1010_01),
.PULLUP(1'b 1)
) sda_buf (
.PACKAGE_PIN(cam_scl),
.OUTPUT_ENABLE(!i2c_gpio[1]),
.D_OUT_0(1'b0),
.D_IN_0(i2c_din[1])
);

assign i2c_din = {cam_scl, cam_sda};
assign cam_sda = i2c_gpio[0] ? 1'bz : 1'b0;
assign cam_scl = i2c_gpio[1] ? 1'bz : 1'b0;
assign cam_enable = 1'b1;

always @(posedge sys_clk) begin
if (reset) begin
i2c_gpio <= 2'b11;
i2c_read <= 2'b11;
i2c_read_last <= 1'b0;
end else if (addr == 16'h0000 && valid) begin
if (wstrb[0])
i2c_gpio <= wdata[1:0];
i2c_read <= i2c_din;
i2c_read_last <= 1'b1;
end else begin
i2c_read_last <= 1'b0;
end
end

@@ -139,8 +161,8 @@ module cameraif(
end
end

assign rdata = (addr == 16'h0000) ? {30'b0, i2c_read} :
{24'b0, ds_read_data};
assign rdata = i2c_read_last ? {30'b0, i2c_read} :
{24'b0, ds_read_data};

// Debugging
reg [22:0] hb_ctr;
@@ -67,12 +67,12 @@ module csi_rx_ice40 #(
.PACKAGE_PIN(dphy_clk_lane),
.D_IN_0(dphy_clk_pre)
);

SB_GB clk_gbuf (
.USER_SIGNAL_TO_GLOBAL_BUFFER(dphy_clk_pre),
.GLOBAL_BUFFER_OUTPUT(dphy_clk)
);

wire dphy_lp;
SB_IO #(
.PIN_TYPE(6'b000001),
@@ -89,25 +89,25 @@ module csi_rx_ice40 #(
else
div <= div + 1'b1;
assign word_clk = div[1];

wire sreset;
reg [7:0] sreset_ctr;
always @(posedge word_clk or posedge areset)
if (areset)
sreset_ctr <= 0;
else if (!(&sreset_ctr))
sreset_ctr <= sreset_ctr + 1'b1;

assign sreset = !(&sreset_ctr);

wire byte_packet_done, wait_for_sync;
wire [LANES*8-1:0] aligned_bytes;
wire [LANES-1:0] aligned_bytes_valid;


generate
genvar ii;
for (ii = 0; ii < LANES; ii++) begin
for (ii = 0; ii < LANES; ii=ii+1) begin
wire [1:0] din_raw;
SB_IO #(
.PIN_TYPE(6'b000000),
@@ -51,7 +51,7 @@ module dphy_rx_byte_align(

reg [7:0] curr_byte;
reg [7:0] last_byte;
reg [7:0] shifted_byte;
wire [7:0] shifted_byte;

reg found_sync;
reg [2:0] sync_offs; // found offset of sync pattern
ProTip! Use n and p to navigate between commits in a pull request.