max2771 spi liens has been added.

This commit is contained in:
onur
2026-08-06 22:14:52 +03:00
parent 847523078b
commit b4920d31e3
288 changed files with 214687 additions and 18389 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,12 +0,0 @@
MARCH=rv64imafdc_zicsr_zifencei
MABI=lp64d
BSP_UART_CLOCK_HZ=50000000
BSP_UART_BAUDRATE=115200
BSP_CLINT_TIMEBASE_HZ=500000
BSP_DTIM_BASE=0x80000000
BSP_DTIM_SIZE=0x00100000
GPS_DEBUG=1
GPS_DEBUG_LEVEL=4
CFLAGS=-march=rv64imafdc_zicsr_zifencei -mabi=lp64d -mcmodel=medany -Os -ffreestanding -fno-builtin -fno-common -Wall -Wextra -I../bsp/include -DBSP_UART_CLOCK_HZ=50000000UL -DBSP_UART_BAUDRATE=115200UL -DBSP_CLINT_TIMEBASE_HZ=500000UL -DBSP_DTIM_BASE=0x80000000UL -DBSP_DTIM_SIZE=0x00100000UL
LDFLAGS=-T ../common/linker_ram.ld -nostartfiles -static -Wl,--gc-sections -Wl,--defsym=__dtim_base=0x80000000 -Wl,--defsym=__dtim_size=0x00100000 -Wl,-Map,/home/onur/Desktop/rocket/rocket-chip/soc/out/software/pmod_spi_test/pmod_spi_test.map
LDLIBS=-Wl,--start-group -lc -lgcc -Wl,--end-group
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large Load Diff
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large Load Diff
+5 -1
View File
@@ -26,7 +26,7 @@ OBJCOPY := $(CROSS)objcopy
READELF := $(CROSS)readelf
MAKE_FLASH_IMAGE := $(SOC_DIR)/software/tools/make_flash_image.py
.PHONY: help all app bootloader hello pmod-spi-test steval-mki217v1-test gps-system flash-image clean
.PHONY: help all app bootloader hello pmod-spi-test max2771-spi-test steval-mki217v1-test gps-system flash-image clean
help:
@echo "Common Rocket bare-metal software targets:"
@@ -35,6 +35,7 @@ help:
@echo " make bootloader # build only BootROM flash bootloader"
@echo " make hello # build only hello UART app"
@echo " make pmod-spi-test # build PMOD SPI smoke test app"
@echo " make max2771-spi-test # build dedicated MAX2771 SPI test app"
@echo " make steval-mki217v1-test # build STEVAL-MKI217V1 LSM6DSOX polling app"
@echo " make gps-system # build imported GPS bare-metal app"
@echo " make flash-image APP=name # build bootloader-readable app flash image"
@@ -63,6 +64,9 @@ hello:
pmod-spi-test:
@make -C pmod_spi_test TOOLCHAIN="$(TOOLCHAIN)" BUILD_DIR="$(OUT_DIR)/pmod_spi_test" BSP_UART_CLOCK_HZ="$(BSP_UART_CLOCK_HZ)" BSP_UART_BAUDRATE="$(BSP_UART_BAUDRATE)" BSP_CLINT_TIMEBASE_HZ="$(BSP_CLINT_TIMEBASE_HZ)" BSP_DTIM_BASE="$(BSP_DTIM_BASE)" BSP_DTIM_SIZE="$(BSP_DTIM_SIZE)" all
max2771-spi-test:
@make -C max2771_spi_test TOOLCHAIN="$(TOOLCHAIN)" BUILD_DIR="$(OUT_DIR)/max2771_spi_test" BSP_UART_CLOCK_HZ="$(BSP_UART_CLOCK_HZ)" BSP_UART_BAUDRATE="$(BSP_UART_BAUDRATE)" BSP_CLINT_TIMEBASE_HZ="$(BSP_CLINT_TIMEBASE_HZ)" BSP_DTIM_BASE="$(BSP_DTIM_BASE)" BSP_DTIM_SIZE="$(BSP_DTIM_SIZE)" all
steval-mki217v1-test:
@make -C steval_mki217v1_test TOOLCHAIN="$(TOOLCHAIN)" BUILD_DIR="$(OUT_DIR)/steval_mki217v1_test" BSP_UART_CLOCK_HZ="$(BSP_UART_CLOCK_HZ)" BSP_UART_BAUDRATE="$(BSP_UART_BAUDRATE)" BSP_CLINT_TIMEBASE_HZ="$(BSP_CLINT_TIMEBASE_HZ)" BSP_DTIM_BASE="$(BSP_DTIM_BASE)" BSP_DTIM_SIZE="$(BSP_DTIM_SIZE)" all
+130
View File
@@ -0,0 +1,130 @@
#include "bsp/max2771_spi.h"
#include "bsp/mmio.h"
#include "bsp/soc.h"
#define MAX2771_COMMAND (BSP_MAX2771_SPI_BASE + 0x00u)
#define MAX2771_WRITE_DATA (BSP_MAX2771_SPI_BASE + 0x04u)
#define MAX2771_READ_DATA (BSP_MAX2771_SPI_BASE + 0x08u)
#define MAX2771_STATUS (BSP_MAX2771_SPI_BASE + 0x0cu)
#define MAX2771_INPUT_CLOCK (BSP_MAX2771_SPI_BASE + 0x10u)
#define MAX2771_SCLK (BSP_MAX2771_SPI_BASE + 0x14u)
#define MAX2771_HALF_PERIOD (BSP_MAX2771_SPI_BASE + 0x18u)
#define MAX2771_IDENT (BSP_MAX2771_SPI_BASE + 0x1cu)
#define MAX2771_STATUS_READY 0x1u
#define MAX2771_STATUS_BUSY 0x2u
#define MAX2771_COMMAND_READ 0x100u
#define MAX2771_IDENT_VALUE 0x4d415831u
#define MAX2771_TIMEOUT_US 1000u
static bsp_max2771_status_t max2771_wait_ready(void)
{
uint64_t timeout_ticks =
((uint64_t)BSP_CLINT_TIMEBASE_HZ * MAX2771_TIMEOUT_US + 999999u) /
1000000u;
if (timeout_ticks == 0u) {
timeout_ticks = 1u;
}
const uint64_t start = bsp_read64(BSP_CLINT_MTIME);
while ((bsp_read32(MAX2771_STATUS) & MAX2771_STATUS_READY) == 0u) {
if ((bsp_read64(BSP_CLINT_MTIME) - start) >= timeout_ticks) {
return BSP_MAX2771_ERR_TIMEOUT;
}
}
return BSP_MAX2771_OK;
}
uint32_t bsp_max2771_status(void)
{
return bsp_read32(MAX2771_STATUS);
}
uint32_t bsp_max2771_input_clock_hz(void)
{
return bsp_read32(MAX2771_INPUT_CLOCK);
}
uint32_t bsp_max2771_sclk_hz(void)
{
return bsp_read32(MAX2771_SCLK);
}
uint32_t bsp_max2771_half_period_cycles(void)
{
return bsp_read32(MAX2771_HALF_PERIOD);
}
bsp_max2771_status_t bsp_max2771_spi_init(void)
{
if (bsp_read32(MAX2771_IDENT) != MAX2771_IDENT_VALUE) {
return BSP_MAX2771_ERR_IP;
}
const uint32_t input_hz = bsp_max2771_input_clock_hz();
const uint32_t sclk_hz = bsp_max2771_sclk_hz();
const uint32_t half_cycles = bsp_max2771_half_period_cycles();
if ((input_hz == 0u) || (half_cycles == 0u) ||
(sclk_hz == 0u) || (sclk_hz > BSP_MAX2771_MAX_SCLK_HZ) ||
(sclk_hz != (input_hz / (2u * half_cycles)))) {
return BSP_MAX2771_ERR_CLOCK;
}
#ifdef BSP_MAX2771_INPUT_CLOCK_HZ
if (input_hz != (uint32_t)BSP_MAX2771_INPUT_CLOCK_HZ) {
return BSP_MAX2771_ERR_CLOCK;
}
#endif
return max2771_wait_ready();
}
bsp_max2771_status_t bsp_max2771_write(uint8_t address, uint32_t value)
{
if (address > BSP_MAX2771_MAX_REGISTER) {
return BSP_MAX2771_ERR_ARGUMENT;
}
bsp_max2771_status_t status = max2771_wait_ready();
if (status != BSP_MAX2771_OK) {
return status;
}
bsp_write32(MAX2771_WRITE_DATA, value);
bsp_write32(MAX2771_COMMAND, (uint32_t)address);
return max2771_wait_ready();
}
bsp_max2771_status_t bsp_max2771_read(uint8_t address, uint32_t *value)
{
if ((address > BSP_MAX2771_MAX_REGISTER) || (value == 0)) {
return BSP_MAX2771_ERR_ARGUMENT;
}
bsp_max2771_status_t status = max2771_wait_ready();
if (status != BSP_MAX2771_OK) {
return status;
}
bsp_write32(MAX2771_COMMAND, MAX2771_COMMAND_READ | (uint32_t)address);
status = max2771_wait_ready();
if (status == BSP_MAX2771_OK) {
*value = bsp_read32(MAX2771_READ_DATA);
}
return status;
}
bsp_max2771_status_t bsp_max2771_write_verified(uint8_t address, uint32_t value)
{
bsp_max2771_status_t status = bsp_max2771_write(address, value);
if (status != BSP_MAX2771_OK) {
return status;
}
uint32_t readback = 0u;
status = bsp_max2771_read(address, &readback);
if (status != BSP_MAX2771_OK) {
return status;
}
return (readback == value) ? BSP_MAX2771_OK : BSP_MAX2771_ERR_VERIFY;
}
@@ -0,0 +1,34 @@
#ifndef BSP_MAX2771_SPI_H
#define BSP_MAX2771_SPI_H
#include <stdint.h>
#define BSP_MAX2771_REGISTER_COUNT 11u
#define BSP_MAX2771_MAX_REGISTER 0x0au
#define BSP_MAX2771_MAX_SCLK_HZ 4000000u
typedef enum {
BSP_MAX2771_OK = 0,
BSP_MAX2771_ERR_ARGUMENT = -1,
BSP_MAX2771_ERR_TIMEOUT = -2,
BSP_MAX2771_ERR_IP = -3,
BSP_MAX2771_ERR_CLOCK = -4,
BSP_MAX2771_ERR_VERIFY = -5
} bsp_max2771_status_t;
/* Validate the dedicated MMIO IP, its board clock, and its idle state. */
bsp_max2771_status_t bsp_max2771_spi_init(void);
/* Execute one complete, hardware-timed 48-SCLK MAX2771 transaction. */
bsp_max2771_status_t bsp_max2771_write(uint8_t address, uint32_t value);
bsp_max2771_status_t bsp_max2771_read(uint8_t address, uint32_t *value);
/* Write then read one register. The readback must equal the written value. */
bsp_max2771_status_t bsp_max2771_write_verified(uint8_t address, uint32_t value);
uint32_t bsp_max2771_input_clock_hz(void);
uint32_t bsp_max2771_sclk_hz(void);
uint32_t bsp_max2771_half_period_cycles(void);
uint32_t bsp_max2771_status(void);
#endif
+1
View File
@@ -6,6 +6,7 @@
#define BSP_UART_BASE 0x10013000UL
#define BSP_SPI_BASE 0x10014000UL
#define BSP_PMOD_SPI_BASE 0x10015000UL
#define BSP_MAX2771_SPI_BASE 0x10016000UL
#define BSP_GPS_ACQ_BASE 0x10020000UL
#define BSP_GPS_TRCK0_BASE 0x10021000UL
#define BSP_GPS_TRCK_STRIDE 0x00001000UL
+12
View File
@@ -0,0 +1,12 @@
TARGET := max2771_spi_test
APP_SRCS := main.c
BSP_SRCS := init.c uart.c max2771_spi.c
# Direct builds default to Genesys 2. Board flows override these values.
BSP_UART_CLOCK_HZ ?= 50000000
BSP_CLINT_TIMEBASE_HZ ?= 500000
BSP_MAX2771_INPUT_CLOCK_HZ ?= $(BSP_UART_CLOCK_HZ)
include ../common/app.mk
CFLAGS += -DBSP_MAX2771_INPUT_CLOCK_HZ=$(BSP_MAX2771_INPUT_CLOCK_HZ)UL
+48
View File
@@ -0,0 +1,48 @@
# MAX2771 SPI Register Test
This bare-metal application exercises the dedicated MAX2771 three-wire SPI IP
at `0x10016000`. It does not use or alter the generic PMOD SPI peripheral.
The test uses the complete default register table from the
[MAX2771 data sheet](https://www.analog.com/media/en/technical-documentation/data-sheets/max2771.pdf).
It writes registers `0x0` through `0xA`, reads each register back immediately,
then performs a second full read sweep and prints all values. Registers `0x0`
and `0x9` therefore receive the mandatory reserved-bit values required after
every MAX2771 power cycle.
Build directly:
```bash
make -C soc/software max2771-spi-test
```
Build through a board flow:
```bash
make -C targets/fpga/genesys2 software APP=max2771_spi_test
make -C targets/fpga/vcu118 software APP=max2771_spi_test
```
For a fast RAM-loaded Genesys 2 test:
```bash
make -C targets/fpga/genesys2 debug-load APP=max2771_spi_test
make -C targets/fpga/genesys2 uart-listen
```
Expected final output is:
```text
PASS,MAX2771 defaults programmed and verified
```
## EV Kit Connection
The EV kit already has a MAX32625 PICO MCU connected to `SPI_CLK`, `SPI_CSN`,
and `SPI_DATA`. Before connecting the FPGA, disconnect that controller or put
all three MCU pins in high impedance and do not run the EV kit GUI. Two active
masters on `SPI_DATA` can cause electrical contention.
Connect `SCLK`, `CSN`, the single bidirectional `SDATA`, and a common ground.
Power the EV kit according to its own guide. Do not connect the FPGA board's
PMOD power pin to an independently powered EV kit.
+81
View File
@@ -0,0 +1,81 @@
#include <stdint.h>
#include <stdio.h>
#include "bsp/max2771_spi.h"
#include "bsp/soc.h"
#include "bsp/uart.h"
/* MAX2771 data sheet Table 2, including the mandatory reserved-bit values. */
static const uint32_t max2771_default_registers[BSP_MAX2771_REGISTER_COUNT] = {
0xbea41603u,
0x20550288u,
0x0eafa1dcu,
0x698c0008u,
0x00c00080u,
0x08000070u,
0x08000000u,
0x010061b2u,
0x01e0f401u,
0x00c00002u,
0x010061b0u
};
static int report_error(const char *operation,
unsigned int address,
bsp_max2771_status_t status)
{
printf("FAIL,%s,reg=0x%x,status=%d\n", operation, address, (int)status);
bsp_uart_wait_tx_idle();
return 1;
}
int main(void)
{
printf("\nMAX2771 dedicated three-wire SPI test\n");
printf("MMIO,0x%08lx\n", (unsigned long)BSP_MAX2771_SPI_BASE);
bsp_max2771_status_t status = bsp_max2771_spi_init();
if (status != BSP_MAX2771_OK) {
return report_error("init", 0u, status);
}
printf("CLOCK,input_hz=%lu,expected_input_hz=%lu,sclk_hz=%lu,half_cycles=%lu,max_hz=%u\n",
(unsigned long)bsp_max2771_input_clock_hz(),
(unsigned long)BSP_MAX2771_INPUT_CLOCK_HZ,
(unsigned long)bsp_max2771_sclk_hz(),
(unsigned long)bsp_max2771_half_period_cycles(),
BSP_MAX2771_MAX_SCLK_HZ);
for (unsigned int address = 0u;
address < BSP_MAX2771_REGISTER_COUNT;
++address) {
status = bsp_max2771_write_verified(
(uint8_t)address, max2771_default_registers[address]);
if (status != BSP_MAX2771_OK) {
return report_error("write_verify", address, status);
}
}
for (unsigned int address = 0u;
address < BSP_MAX2771_REGISTER_COUNT;
++address) {
uint32_t value = 0u;
status = bsp_max2771_read((uint8_t)address, &value);
if (status != BSP_MAX2771_OK) {
return report_error("read", address, status);
}
printf("REGISTER,0x%x,0x%08lx\n", address, (unsigned long)value);
if (value != max2771_default_registers[address]) {
printf("FAIL,read_verify,reg=0x%x,expected=0x%08lx,actual=0x%08lx\n",
address,
(unsigned long)max2771_default_registers[address],
(unsigned long)value);
bsp_uart_wait_tx_idle();
return 1;
}
}
printf("PASS,MAX2771 defaults programmed and verified\n");
bsp_uart_wait_tx_idle();
return 0;
}