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 1 commit
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Adding firmware for camera

Signed-off-by: David Shah <davey1576@gmail.com>
  • Loading branch information
daveshah1 authored and elms committed Oct 29, 2018
commit 7ac93f9c26cc122e54a5da478c5477ab2e68515d
@@ -48,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
@@ -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 uint32_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,6 +114,7 @@ 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),
@@ -141,10 +142,14 @@ module cameraif(
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

@@ -156,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
@@ -94,7 +94,7 @@ module dphy_rx_byte_align(
found_sync = 1'b0;
sync_offs = 0;
for (i = 0; i < 8; i = i + 1) begin
if ((concat_word[(1+i) +: 8] == sync_word) && (last_byte[i:0] == 0)) begin
if ((concat_word[(1+i) +: 8] == sync_word) /*&& (last_byte[i:0] == 0)*/) begin
was_found = 1'b1;
offset = i;
end
@@ -213,6 +213,9 @@ module ctrlsoc (
addr_flash: begin
buserror <= |mem_wstrb;
end
addr_camera: begin
/* nothing to do here */
end
mem_addr == 32'h 02000000: begin
mem_ready <= 1;
if (mem_wstrb[0]) begin
@@ -21,6 +21,8 @@
#include <stdint.h>
#include <stdbool.h>

#include "camera/camera.h"

// a pointer to this is a null pointer, but the compiler does not
// know that because "sram" is a linker symbol from sections.lds.
extern uint32_t sram;
@@ -413,8 +415,11 @@ void main()
{
print("\n\n\n\n\n");
print("Booting..\n");

ml_test();
print("\n");
camera_init();
print ("Initialised camera\n");

reg_leds = 127;
while (!RUN_LOOP) {
@@ -76,6 +76,8 @@ module testbench;
wire ml_csb;
wire ml_clk;

wire cam_scl = 1'b0, cam_sda = 1'b0;

ctrlsoc ctrl (
.clk (ctrl_clk ),

@@ -99,7 +101,10 @@ module testbench;
.led5 (led5 ),

.ml_csb (ml_csb ),
.ml_clk (ml_clk )
.ml_clk (ml_clk ),

.cam_scl (cam_scl),
.cam_sda (cam_sda)
);

spiflash flash (
ProTip! Use n and p to navigate between commits in a pull request.