Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions source/application/lua_libraries/camera.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,21 @@ static int lua_camera_capture(lua_State *L)
return 0;
}

static int lua_camera_image_ready(lua_State *L)
{
if (nrf_gpio_pin_out_read(CAMERA_SLEEP_PIN) == false)
{
luaL_error(L, "camera is asleep");
}

uint8_t data[1] = {0};

spi_read(FPGA, 0x27, (uint8_t *)data, sizeof(data));

lua_pushboolean(L, data[0] == 1);
return 1;
}

static uint16_t get_bytes_available(void)
{
uint8_t data[2] = {0, 0};
Expand Down Expand Up @@ -695,6 +710,9 @@ void lua_open_camera_library(lua_State *L)
lua_pushcfunction(L, lua_camera_capture);
lua_setfield(L, -2, "capture");

lua_pushcfunction(L, lua_camera_image_ready);
lua_setfield(L, -2, "image_ready");

lua_pushcfunction(L, lua_camera_read);
lua_setfield(L, -2, "read");

Expand Down
49,393 changes: 24,611 additions & 24,782 deletions source/fpga/fpga_application.h

Large diffs are not rendered by default.

19 changes: 12 additions & 7 deletions source/fpga/modules/camera/camera.sv
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ logic [10:0] y_resolution = 512;
logic [10:0] x_pan = 0;
logic [1:0] compression_factor;

logic [15:0] bytes_available;
logic image_buffer_ready;
logic [15:0] image_buffer_total_size;
logic [7:0] image_buffer_data;
logic [15:0] image_buffer_address;

Expand Down Expand Up @@ -86,9 +87,10 @@ spi_registers spi_registers (
// .x_pan_out(x_pan),
.compression_factor_out(compression_factor),

.bytes_available_in(bytes_available),
.data_in(image_buffer_data),
.bytes_read_out(image_buffer_address),
.image_ready_in(image_buffer_ready),
.image_total_size_in(image_buffer_total_size),
.image_data_in(image_buffer_data),
.image_address_out(image_buffer_address),

.red_center_metering_in(red_center_metering_spi_clock_domain),
.green_center_metering_in(green_center_metering_spi_clock_domain),
Expand Down Expand Up @@ -368,6 +370,7 @@ crop zoom_crop (
logic [31:0] final_image_data;
logic [15:0] final_image_address;
logic final_image_data_valid;
logic final_image_ready;

jpeg_encoder jpeg_encoder (
.pixel_clock_in(pixel_clock_in),
Expand All @@ -390,10 +393,10 @@ jpeg_encoder jpeg_encoder (
.data_out(final_image_data),
.data_valid_out(final_image_data_valid),
.address_out(final_image_address),
.image_valid_out()
.image_valid_out(final_image_ready)
);

always_comb bytes_available = final_image_address + 4;
always_comb image_buffer_total_size = final_image_address + 4;

image_buffer image_buffer (
.write_clock_in(pixel_clock_in),
Expand All @@ -404,7 +407,9 @@ image_buffer image_buffer (
.read_address_in(image_buffer_address),
.write_data_in(final_image_data),
.read_data_out(image_buffer_data),
.write_read_n_in(final_image_data_valid)
.write_read_n_in(final_image_data_valid),
.write_complete_in(final_image_ready),
.write_complete_out(image_buffer_ready)
);

endmodule
29 changes: 28 additions & 1 deletion source/fpga/modules/camera/image_buffer.sv
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,10 @@ module image_buffer (
input logic [31:0] write_data_in,
output logic [7:0] read_data_out,

input logic write_read_n_in
input logic write_read_n_in,

input logic write_complete_in,
output logic write_complete_out
);

// Write to read CDC
Expand Down Expand Up @@ -80,6 +83,30 @@ always @(posedge read_clock_in) begin : cdc

end

// Write complete CDC
logic [2:0] write_complete_cdc;

always @(posedge read_clock_in) begin : cdc2

if (read_reset_n_in == 0) begin
write_complete_out <= 0;
write_complete_cdc <= 0;
end

else begin
write_complete_cdc <= {write_complete_cdc[1:0], write_complete_in};

if (write_complete_cdc[2]) begin
write_complete_out <= 1;
end

else begin
write_complete_out <= 0;
end
end

end

// Read/write selection
logic [13:0] address;
assign address = write_enable ? write_address : read_address_in[15:2];
Expand Down
25 changes: 16 additions & 9 deletions source/fpga/modules/camera/spi_registers.sv
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,10 @@
// TODO position signals
output logic [1:0] compression_factor_out,

input logic [15:0] bytes_available_in,
input logic [7:0] data_in,
output logic [15:0] bytes_read_out,
input logic image_ready_in,
input logic [15:0] image_total_size_in,
input logic [7:0] image_data_in,
output logic [15:0] image_address_out,

input logic [7:0] red_center_metering_in,
input logic [7:0] green_center_metering_in,
Expand All @@ -39,7 +40,7 @@
);

logic [15:0] bytes_remaining;
assign bytes_remaining = bytes_available_in - bytes_read_out;
assign bytes_remaining = image_total_size_in - image_address_out;

logic [1:0] operand_valid_in_edge_monitor;

Expand All @@ -53,7 +54,7 @@ always_ff @(posedge clock_in) begin
// TODO position signals
compression_factor_out <= 0;

bytes_read_out <= 0;
image_address_out <= 0;

operand_valid_in_edge_monitor <= 0;
end
Expand All @@ -69,7 +70,7 @@ always_ff @(posedge clock_in) begin
// Capture
'h20: begin
start_capture_out <= 1;
bytes_read_out <= 0;
image_address_out <= 0;
end

// Bytes available
Expand All @@ -84,11 +85,11 @@ always_ff @(posedge clock_in) begin

// Read data
'h22: begin
response_out <= data_in;
response_out <= image_data_in;

if (operand_valid_in_edge_monitor == 2'b01) begin
if (bytes_read_out < bytes_available_in) begin
bytes_read_out <= bytes_read_out + 1;
if (image_address_out < image_total_size_in) begin
image_address_out <= image_address_out + 1;
end
end

Expand Down Expand Up @@ -130,6 +131,12 @@ always_ff @(posedge clock_in) begin
end
end

// Image ready flag
'h27: begin
response_out <= {7'b0, image_ready_in};
response_valid_out <= 1;
end

endcase

end
Expand Down
15 changes: 12 additions & 3 deletions tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Tests the Frame specific Lua libraries over Bluetooth.
"""

import asyncio
import asyncio, sys
from frameutils import Bluetooth


Expand Down Expand Up @@ -159,9 +159,18 @@ async def main():

# Camera

## Capture in different modes
## Test capture and ready flag
await test.lua_send("frame.camera.capture{}")
await test.lua_send("frame.sleep(0.1)")
await test.lua_equals("frame.camera.image_ready()", "false")
await test.lua_send("frame.sleep(0.05)")
await test.lua_equals("frame.camera.image_ready()", "true")

await test.lua_send("frame.camera.capture{}")
await test.lua_equals("frame.camera.image_ready()", "false")
await test.lua_send("frame.sleep(0.05)")
await test.lua_equals("frame.camera.image_ready()", "true")

## Capture in different modes
await test.lua_send("frame.camera.capture{quality_factor=10}")
await test.lua_send("frame.sleep(0.1)")
await test.lua_send("frame.camera.capture{quality_factor=25}")
Expand Down
6 changes: 3 additions & 3 deletions tests/test_camera_fps.py
Original file line number Diff line number Diff line change
Expand Up @@ -669,10 +669,10 @@ async def main():
state_time = frame.time.utc()
state = 'WAIT'
elseif state == 'WAIT' then
if frame.time.utc() > state_time + 0.1 then
state = 'SEND'
if frame.camera.image_ready() then
state = 'READ'
end
elseif state == 'SEND' then
elseif state == 'READ' then
local i = frame.camera.read_raw(frame.bluetooth.max_length() - 1)
if (i == nil) then
state = 'DONE'
Expand Down