Skip to content
Open
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
15 changes: 14 additions & 1 deletion firmware/common/firmware_info.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,23 @@
#define DFU_MODE_VALUE 0
#endif

#if defined(IS_PRALINE) && defined(BITSTREAM_AVAILABLE) && \
!(defined(RAM_MODE) || defined(DFU_MODE))
#define POINT_TO_BITSTREAM
extern uint32_t _binary_fpga_bin_start;
#endif

__attribute__((section(".firmware_info"))) const struct firmware_info_t firmware_info = {
.magic = "HACKRFFW",
.magic = FIRMWARE_INFO_MAGIC,
.struct_version = 1,
.dfu_mode = DFU_MODE_VALUE,
.supported_platform = SUPPORTED_PLATFORM,
.version_string = VERSION_STRING,
.more_magic = FIRMWARE_INFO_MORE_MAGIC,
.minor_version = 1,
#ifdef POINT_TO_BITSTREAM
.bitstream_flash_addr = (uint32_t) &_binary_fpga_bin_start,
#else
.bitstream_flash_addr = 0,
#endif
};
6 changes: 6 additions & 0 deletions firmware/common/firmware_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,18 @@

#include <stdint.h>

#define FIRMWARE_INFO_MAGIC "HACKRFFW"
#define FIRMWARE_INFO_MORE_MAGIC "MITPDP10"

struct firmware_info_t {
__attribute__((nonstring)) char magic[8];
uint16_t struct_version;
uint16_t dfu_mode;
uint32_t supported_platform;
char version_string[32];
__attribute__((nonstring)) char more_magic[8];
uint32_t minor_version;
uint32_t bitstream_flash_addr;
} __attribute__((packed, aligned(1)));

extern const struct firmware_info_t firmware_info;
4 changes: 2 additions & 2 deletions firmware/common/fpga.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ struct fpga_loader_t {
/* Start address added as an offset to all read() calls. */
uint32_t start_addr;
/* Any one-off setup needed before calling read(). May be NULL. */
void (*setup)(void);
bool (*setup)(void);
/* Read data from the specified address. */
void (*read)(uint32_t addr, uint32_t len, uint8_t* const data);
bool (*read)(uint32_t addr, uint32_t len, uint8_t* const data);
/* Buffer to use for compressed data (4096 bytes). */
uint8_t* in_buffer;
/* Buffer to use for decompressed data (4096 bytes). */
Expand Down
29 changes: 13 additions & 16 deletions firmware/common/fpga_image.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
#include "fpga.h"
#include "ice40_spi.h"
#include "lz4_blk.h"
#include "selftest.h"

struct fpga_image_read_ctx {
struct fpga_loader_t* loader;
Expand Down Expand Up @@ -57,9 +56,11 @@ static size_t fpga_image_read_block_cb(void* _ctx)
return 0;

// Read compressed block (and the next block size) from flash.
loader->read(ctx->addr, block_sz, loader->in_buffer);
if (!loader->read(ctx->addr, block_sz, loader->in_buffer))
return 0;
ctx->addr += block_sz;
loader->read(ctx->addr, 2, block_sz_buf);
if (!loader->read(ctx->addr, 2, block_sz_buf))
return 0;
ctx->next_block_sz = block_sz_buf[0] | block_sz_buf[1] << 8;
ctx->addr += 2;

Expand All @@ -70,17 +71,21 @@ static size_t fpga_image_read_block_cb(void* _ctx)
bool fpga_image_load(struct fpga_loader_t* loader, unsigned int index)
{
// TODO: do SPI setup and read number of bitstreams once!
if (loader->setup != NULL)
loader->setup();
if (loader->setup != NULL) {
if (!loader->setup())
return false;
}

// Read number of bitstreams from flash.
// Check the bitstream exists, and extract its offset.
uint32_t addr = loader->start_addr;
uint32_t num_bitstreams, bitstream_offset;
loader->read(addr, 4, (uint8_t*) &num_bitstreams);
if (!loader->read(addr, 4, (uint8_t*) &num_bitstreams))
return false;
if (index >= num_bitstreams)
return false;
loader->read(addr + 4 * (index + 1), 4, (uint8_t*) &bitstream_offset);
if (!loader->read(addr + 4 * (index + 1), 4, (uint8_t*) &bitstream_offset))
return false;

// A callback function is used by the FPGA programmer
// to obtain consecutive gateware chunks.
Expand All @@ -89,17 +94,9 @@ bool fpga_image_load(struct fpga_loader_t* loader, unsigned int index)
.loader = loader,
.addr = loader->start_addr + bitstream_offset,
};
const bool success = ice40_spi_syscfg_program(
return ice40_spi_syscfg_program(
&ice40,
loader->out_buffer,
fpga_image_read_block_cb,
&fpga_image_ctx);

// Update selftest result.
selftest.fpga_image_load = success ? PASSED : FAILED;
if (selftest.fpga_image_load != PASSED) {
selftest.report.pass = false;
}

return success;
}
43 changes: 25 additions & 18 deletions firmware/hackrf_usb/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,21 @@ add_custom_command(
DEPENDS ${PATH_CPLD_BITSTREAM_TOOL} ${PATH_HACKRF_CPLD_XSVF}
)

add_custom_command(
OUTPUT ${PATH_PRALINE_FPGA_OBJ}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMAND ${CMAKE_COMMAND} -E copy ${PATH_PRALINE_FPGA_BIN} "fpga.bin"
COMMAND ${CMAKE_OBJCOPY}
-I binary
-O elf32-littlearm
-B arm
--rename-section .data=.rom_only
"fpga.bin" ${PATH_PRALINE_FPGA_OBJ}
DEPENDS ${PATH_PRALINE_FPGA_BIN}
)
if(NOT DEFINED EXCLUDE_BITSTREAM)
add_definitions(-DBITSTREAM_AVAILABLE)
add_custom_command(
OUTPUT ${PATH_PRALINE_FPGA_OBJ}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMAND ${CMAKE_COMMAND} -E copy ${PATH_PRALINE_FPGA_BIN} "fpga.bin"
COMMAND ${CMAKE_OBJCOPY}
-I binary
-O elf32-littlearm
-B arm
--rename-section .data=.rom_only
"fpga.bin" ${PATH_PRALINE_FPGA_OBJ}
DEPENDS ${PATH_PRALINE_FPGA_BIN}
)
endif()

set(SRC_M4
hackrf_usb.c
Expand Down Expand Up @@ -89,9 +92,11 @@ if(BOARD STREQUAL "UNIVERSAL")
"${PATH_HACKRF_FIRMWARE_COMMON}/fpga_selftest.c"
usb_api_praline.c
)
SET(OBJ_M4
${PATH_PRALINE_FPGA_OBJ}
)
if (NOT DEFINED EXCLUDE_BITSTREAM)
SET(OBJ_M4
${PATH_PRALINE_FPGA_OBJ}
)
endif()
endif()

if(BOARD STREQUAL "PRALINE")
Expand All @@ -102,9 +107,11 @@ if(BOARD STREQUAL "PRALINE")
"${PATH_HACKRF_FIRMWARE_COMMON}/fpga_selftest.c"
usb_api_praline.c
)
SET(OBJ_M4
${PATH_PRALINE_FPGA_OBJ}
)
if (NOT DEFINED EXCLUDE_BITSTREAM)
SET(OBJ_M4
${PATH_PRALINE_FPGA_OBJ}
)
endif()
else()
SET(SRC_M4
${SRC_M4}
Expand Down
65 changes: 41 additions & 24 deletions firmware/hackrf_usb/hackrf_usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,9 @@
#endif
#ifdef IS_PRALINE
#include <fpga.h>
#if !(defined(DFU_MODE) || defined(RAM_MODE))
#include <lz4_buf.h>
#include <spi_bus.h>
#include <w25q80bv.h>
#endif
#include <firmware_info.h>
#include <lz4_buf.h>
#include <w25q80bv.h>
#endif

#include "usb_api_adc.h"
Expand Down Expand Up @@ -271,26 +269,47 @@ static void m0_rom_to_ram(void)
memcpy(dest, (uint32_t*) (base + src), len);
}

#if defined(IS_PRALINE) && !(defined(DFU_MODE) || defined(RAM_MODE))
extern uint32_t _binary_fpga_bin_start;
#if defined(IS_PRALINE)

bool fpga_loader_setup(void);
bool fpga_loader_read(uint32_t addr, uint32_t size, uint8_t* buf);

struct fpga_loader_t fpga_loader = {
.start_addr = 0,
.setup = fpga_loader_setup,
.read = fpga_loader_read,
.in_buffer = lz4_in_buf,
.out_buffer = lz4_out_buf,
};

void fpga_loader_setup(void)
bool fpga_loader_setup(void)
{
w25q80bv_setup(&spi_flash);

/* Read firmware info from start of flash, after vector table */
struct firmware_info_t info;
w25q80bv_read(&spi_flash, 0x400, sizeof(info), (uint8_t*) &info);

/* Check for valid firmware info with bitstream address present. */
bool bitstream_found = !memcmp(info.magic, FIRMWARE_INFO_MAGIC, 8) &&
info.struct_version == 1 &&
!memcmp(info.more_magic, FIRMWARE_INFO_MORE_MAGIC, 8) &&
info.minor_version >= 1;

if (bitstream_found) {
fpga_loader.start_addr = info.bitstream_flash_addr;
return true;
} else {
return false;
}
}

void fpga_loader_read(uint32_t addr, uint32_t size, uint8_t* buf)
bool fpga_loader_read(uint32_t addr, uint32_t size, uint8_t* buf)
{
w25q80bv_read(&spi_flash, addr, size, buf);
return true;
}

struct fpga_loader_t fpga_loader = {
.start_addr = (uint32_t) &_binary_fpga_bin_start,
.setup = fpga_loader_setup,
.read = fpga_loader_read,
.in_buffer = lz4_in_buf,
.out_buffer = lz4_out_buf,
};
#endif

void radio_changed(const uint32_t changed)
Expand Down Expand Up @@ -446,15 +465,13 @@ int main(void)
#ifdef IS_PRALINE
if (IS_PRALINE) {
enable_3v3aux_power();
#if !defined(DFU_MODE) && !defined(RAM_MODE)
enable_1v2_power();
enable_rf_power();
/*
* On Praline, the clock generator power supply comes from 3V3FPGA
* which is enabled when 1V2FPGA is turned on.
*/
clock_gen_init();
#endif
}
#endif
#ifdef IS_NOT_PRALINE
Expand Down Expand Up @@ -508,12 +525,12 @@ int main(void)
#endif
#ifdef IS_PRALINE
if (IS_PRALINE) {
#if defined(DFU_MODE) || defined(RAM_MODE)
selftest.fpga_image_load = SKIPPED;
selftest.report.pass = false;
#else
fpga_image_load(&fpga_loader, 0);
#endif
if (fpga_image_load(&fpga_loader, 0)) {
selftest.fpga_image_load = PASSED;
} else {
selftest.fpga_image_load = FAILED;
selftest.report.pass = false;
}
delay_us(100);
fpga_spi_selftest();
fpga_sgpio_selftest();
Expand Down
10 changes: 1 addition & 9 deletions firmware/hackrf_usb/usb_api_praline.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,7 @@
#include <usb_queue.h>
#include <usb_request.h>
#include <usb_type.h>
#if !defined(DFU_MODE) && !defined(RAM_MODE)
#include <fpga.h>
#endif
#include <fpga.h>

usb_request_status_t usb_vendor_request_p1_ctrl(
usb_endpoint_t* const endpoint,
Expand Down Expand Up @@ -97,11 +95,6 @@ usb_request_status_t usb_vendor_request_set_fpga_bitstream(
usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage)
{
#if defined(DFU_MODE) || defined(RAM_MODE)
(void) endpoint;
(void) stage;
return USB_REQUEST_STATUS_STALL;
#else
extern struct fpga_loader_t fpga_loader;

if (detected_platform() != BOARD_ID_PRALINE) {
Expand All @@ -115,5 +108,4 @@ usb_request_status_t usb_vendor_request_set_fpga_bitstream(
usb_transfer_schedule_ack(endpoint->in);
}
return USB_REQUEST_STATUS_OK;
#endif
}
Loading