#include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> #include <sys/mman.h>

#define MAP_SIZE 4096UL #define MAP_MASK (MAP_SIZE - 1)

#define XPAR_PS7_SPI_0_S00_AXI_BASEADDR 0x43C00000 #define XPAR_PS7_SPI_0_S00_AXI_HIGHADDR 0x43C0FFFF

#define XPAR_PS7_GPIO_0_BASEADDR 0xE000A000 #define XPAR_PS7_GPIO_0_HIGHADDR 0xE000AFFF

#define SPI_RESET_BIT 0x00000001 #define SPI_SS_BIT 0x00000002 #define SPI_STOP_BIT 0x00000004 #define SPI_START_BIT 0x00000008 #define SPI_DONE_BIT 0x00000010

#define CDCM_ADDR 0x4B

#define SPI_COMMAND_SIZE 3 // 3 bytes #define SPI_DATA_SIZE 2 // 2 bytes

#define CDCM_REG0_ADDR 0x0 #define CDCM_REG1_ADDR 0x1 #define CDCM_REG2_ADDR 0x2 #define CDCM_REG3_ADDR 0x3

#define CDCM_SPI_CLK_HZ 1000000 // SPI clock frequency

// CDCM6208 register values for 100 MHz output frequency #define CDCM_REG0_VAL 0x38 #define CDCM_REG1_VAL 0x04 #define CDCM_REG2_VAL 0x0A #define CDCM_REG3_VAL 0x00

int main() { int fd; void *spi_map; void *gpio_map;

volatile unsigned int *spi_baseaddr;
volatile unsigned int *gpio_baseaddr;

unsigned int spi_control;
unsigned int spi_command[SPI_COMMAND_SIZE];
unsigned int spi_data[SPI_DATA_SIZE];
unsigned int spi_status;

unsigned char cdcmd[SPI_COMMAND_SIZE] = {0x00, CDCM_ADDR, 0x00};
unsigned char cddata[SPI_DATA_SIZE] = {0x00, 0x00};

// Open /dev/mem and map the physical memory space of the SPI and GPIO peripherals into virtual memory space
if ((fd = open('/dev/mem', O_RDWR | O_SYNC)) < 0)
{
    printf('Error: cannot open /dev/mem\n');
    return -1;
}

spi_map = mmap(NULL, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, XPAR_PS7_SPI_0_S00_AXI_BASEADDR & ~MAP_MASK);
gpio_map = mmap(NULL, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, XPAR_PS7_GPIO_0_BASEADDR & ~MAP_MASK);

if (spi_map == MAP_FAILED || gpio_map == MAP_FAILED)
{
    printf('Error: mmap failed\n');
    return -1;
}

spi_baseaddr = (volatile unsigned int *) (spi_map + (XPAR_PS7_SPI_0_S00_AXI_BASEADDR & MAP_MASK));
gpio_baseaddr = (volatile unsigned int *) (gpio_map + (XPAR_PS7_GPIO_0_BASEADDR & MAP_MASK));

// Enable the SPI peripheral
spi_control = *(spi_baseaddr + 0x10);
spi_control |= 0x00000003;
*(spi_baseaddr + 0x10) = spi_control;

// Configure the SPI peripheral
spi_control = *(spi_baseaddr + 0x04);
spi_control &= ~0x00000001; // Master mode
spi_control &= ~0x00000002; // CPOL=0, CPHA=0
spi_control &= ~0x00000004; // MSB first
spi_control &= ~0x00000008; // Manual chip select
spi_control &= ~0x00000010; // Active low chip select
spi_control &= ~0x00000020; // Transfers on rising edge
spi_control &= ~0x00000040; // Ignore slave output
spi_control &= ~0x00000080; // Normal mode
spi_control &= ~0x00000100; // Loopback disabled
spi_control &= ~0x00000200; // Interrupts disabled
spi_control |= 0x00000400; // SPI clock is sourced from PS clock
spi_control &= ~0x00000800; // Disable slave select 1
spi_control &= ~0x00001000; // Disable slave select 2
spi_control &= ~0x00002000; // Disable slave select 3
spi_control |= 0x00004000; // Enable burst mode
spi_control &= ~0x00008000; // Disable FIFO
spi_control &= ~0x00010000; // Clear RX FIFO
spi_control &= ~0x00020000; // Clear TX FIFO
spi_control &= ~0x00040000; // Enable manual start
spi_control &= ~0x00080000; // Disable manual stop
spi_control &= ~0x00100000; // Disable auto-restart
spi_control &= ~0x00200000; // Disable TX empty interrupt
spi_control &= ~0x00400000; // Disable RX full interrupt
spi_control &= ~0x00800000; // Disable slave idle interrupt
spi_control &= ~0x01000000; // Disable TX underrun interrupt
spi_control &= ~0x02000000; // Disable RX overrun interrupt
*(spi_baseaddr + 0x04) = spi_control;

// Configure the CDCM6208 for 100 MHz output frequency
cdcmd[1] = CDCM_ADDR;
cdcmd[2] = CDCM_REG0_ADDR;
spi_command[0] = cdcmd[0];
spi_command[1] = cdcmd[1];
spi_command[2] = cdcmd[2];
spi_status = SPI_START_BIT | SPI_SS_BIT | SPI_RESET_BIT;
*(spi_baseaddr + 0x08) = spi_status;
spi_status = SPI_STOP_BIT | SPI_SS_BIT;
*(spi_baseaddr + 0x08) = spi_status;
spi_status = SPI_START_BIT | SPI_SS_BIT;
*(spi_baseaddr + 0x08) = spi_status;
spi_status = SPI_SS_BIT;
*(spi_baseaddr + 0x08) = spi_status;
for (int i = 0; i < SPI_COMMAND_SIZE; i++)
{
    spi_command[i] = cdcmd[i];
    spi_status = SPI_SS_BIT;
    *(spi_baseaddr + 0x08) = spi_status;
    *(spi_baseaddr + 0x0C) = spi_command[i];
    spi_status = SPI_SS_BIT | SPI_START_BIT;
    *(spi_baseaddr + 0x08) = spi_status;
    while (!(*(spi_baseaddr + 0x14) & SPI_DONE_BIT));
    spi_status = SPI_SS_BIT | SPI_STOP_BIT;
    *(spi_baseaddr + 0x08) = spi_status;
}
cddata[0] = *(spi_baseaddr + 0x10) & 0x0000FFFF;
spi_status = SPI_START_BIT | SPI_SS_BIT | SPI_RESET_BIT;
*(spi_baseaddr + 0x08) = spi_status;
spi_status = SPI_STOP_BIT | SPI_SS_BIT;
*(spi_baseaddr + 0x08) = spi_status;
spi_status = SPI_START_BIT | SPI_SS_BIT;
*(spi_baseaddr + 0x08) = spi_status;
spi_status = SPI_SS_BIT;
*(spi_baseaddr + 0x08) = spi_status;
cdcmd[2] = CDCM_REG1_ADDR;
spi_command[0] = cdcmd[0];
spi_command[1] = cdcmd[1];
spi_command[2] = cdcmd[2];
for (int i = 0; i < SPI_COMMAND_SIZE; i++)
{
    spi_command[i] = cdcmd[i];
    spi_status = SPI_SS_BIT;
    *(spi_baseaddr + 0x08) = spi_status;
    *(spi_baseaddr + 0x0C) = spi_command[i];
    spi_status = SPI_SS_BIT | SPI_START_BIT;
    *(spi_baseaddr + 0x08) = spi_status;
    while (!(*(spi_baseaddr + 0x14) & SPI_DONE_BIT));
    spi_status = SPI_SS_BIT | SPI_STOP_BIT;
    *(spi_baseaddr + 0x08) = spi_status;
}
cddata[1] = *(spi_baseaddr + 0x10) & 0x0000FFFF;
spi_status = SPI_START_BIT | SPI_SS_BIT | SPI_RESET_BIT;
*(spi_baseaddr + 0x08) = spi_status;
spi_status = SPI_STOP_BIT | SPI_SS_BIT;
*(spi_baseaddr + 0x08) = spi_status;
spi_status = SPI_START_BIT | SPI_SS_BIT;
*(spi_baseaddr + 0x08) = spi_status;
spi_status = SPI_SS_BIT;
*(spi_baseaddr + 0x08) = spi_status;
cdcmd[2] = CDCM_REG2_ADDR;
spi_command[0] = cdcmd[0];
spi_command[1] = cdcmd[1];
spi_command[2] = cdcmd[2];
for (int i = 0; i < SPI_COMMAND_SIZE; i++)
{
    spi_command[i] = cdcmd[i];
    spi_status = SPI_SS_BIT;
    *(spi_baseaddr + 0x08) = spi_status;
    *(spi_baseaddr + 0x0C) = spi_command[i];
    spi_status = SPI_SS_BIT | SPI_START_BIT;
    *(spi_baseaddr + 0x08) = spi_status;
    while (!(*(spi_baseaddr + 0x14) & SPI_DONE_BIT));
    spi_status = SPI_SS_BIT | SPI_STOP_BIT;
    *(spi_baseaddr + 0x08) = spi_status;
}
cddata[0] = *(spi_baseaddr + 0x10) & 0x0000FFFF;
spi_status = SPI_START_BIT | SPI_SS_BIT | SPI_RESET_BIT;
*(spi_baseaddr + 0x08) = spi_status;
spi_status = SPI_STOP_BIT | SPI_SS_BIT;
*(spi_baseaddr + 0x08) = spi_status;
spi_status = SPI_START_BIT | SPI_SS_BIT;
*(spi_baseaddr + 0x08) = spi_status;
spi_status = SPI_SS_BIT;
*(spi_baseaddr + 0x08) = spi_status;
cdcmd[2] = CDCM_REG3_ADDR;
spi_command[0] = cdcmd[0];
spi_command[1] = cdcmd[1];
spi_command[2] = cdcmd[2];
for (int i = 0; i < SPI_COMMAND_SIZE; i++)
{
    spi_command[i] = cdcmd[i];
    spi_status = SPI_SS_BIT;
    *(spi_baseaddr + 0x08) = spi_status;
    *(spi_baseaddr + 0x0C) = spi_command[i];
    spi_status = SPI_SS_BIT | SPI_START_BIT;
    *(spi_baseaddr + 0x08) = spi_status;
    while (!(*(spi_baseaddr + 0x14) & SPI_DONE_BIT));
    spi_status = SPI_SS_BIT | SPI_STOP_BIT;
    *(spi_baseaddr + 0x08) = spi_status;
}
cddata[1] = *(spi_baseaddr + 0x10) & 0x0000FFFF;
spi_status = SPI_START_BIT | SPI_SS_BIT | SPI_RESET_BIT;
*(spi_baseaddr + 0x08) = spi_status;
spi_status = SPI_STOP_BIT | SPI_SS_BIT;
*(spi_baseaddr + 0x08) = spi_status;

// Print the CDCM6208 register values
printf('CDCM6208 register values:\n');
printf('Register 0: 0x%02X\n', cddata[0]);
printf('Register 1: 0x%02X\n', cddata[1] >> 8);
printf('Register 2: 0x%02X\n', cddata[1] & 0x00FF);
printf('Register 3: 0x%02X\n', cddata[0] >> 8);

// Unmap the memory spaces and close /dev/mem
munmap(spi_map, MAP_SIZE);
munmap(gpio_map, MAP_SIZE);
close(fd);

return 0;

}

Zynq7100 PS端SPI接口配置CDCM6208输出频率C++代码示例

原文地址: https://www.cveoy.top/t/topic/nRsZ 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录