max2771 spi liens has been added.
This commit is contained in:
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
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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.
|
||||
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user