AXILITE_IN模块与AXILITE_OUT模块,主要是从AXI总线上接收数据或者发送数据,然后在PL侧将REG数据映射到对应的PORT上去。
所以,我们封装这两个模块时,需要关联或者内嵌一个IOMEM资源,这里选择内嵌方式。
#include "io_mem.h"
#define FPGA_CLARITY_VALUE_MASK GENMASK(31, 0)
#define FPGA_CLARITY_VALUE_SHIFT 0
#define FPGA_FOCUS_MOTOR_REACH BIT(0)
class AxiLiteIn
{
public:
AxiLiteIn(u32 phy_base, u32 size) {
regs_.phy_base_ = phy_base;
regs_.total_size_ = size;
}
u32 get_clarity_value() {
return regs_.get_value(0);
}
u32 get_motor_reach() {
u32 data = regs_.get_value(1, 0);
return (data & FPGA_FOCUS_MOTOR_REACH) ? 1 : 0;
}
void get_rgb_win_sum(WinSum& value) {
int k = 0;
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
value.data_[j][i] = regs_.get_value(2 + k, 0);
k++;
}
}
}
u32 get_bayer_sum() {
return regs_.get_value(18, 0);
}
u32 get_bayer_cnt() {
return regs_.get_value(19, 0);
}
u8 get_photo_vs() {
u32 data = regs_.get_value(20, 0);
return (u8)(data & 0x1);
}
u8 get_video_lock() {
u32 data = regs_.get_value(21, 0);
return (u8)(data & 0x1);
}
u8 get_photo_lock() {
u32 data = regs_.get_value(21, 0);
return (u8)((data >> 1) & 0x1);
}
protected:
IoMem regs_;
};
这里,引用了一个class,即winsum,它只有数据,并没有方法,可以定义成struct,也可以定义成class,这里选择定义成class,方便以后扩展它的功能,添加操作集。
class WinSum
{
public:
u32 data_[4][4];
};
再看看axilite_out模块。
#include "io_mem.h"
#define AXILITE_OUT_STEREO_MATCH_RESET BIT(0)
#define AXILITE_OUT_STEREO_MATCH_VS_IN BIT(1)
#define AXILITE_OUT_STEREO_MATCH_MODE_MASK GENMASK(11, 8)
#define AXILITE_OUT_STEREO_MATCH_MODE_SHIFT 8
//-------------------------------------- 寄存器偏移 输出 ---------------------------------------------//
#define FPGA_LOW16_MASK GENMASK(15, 0)
#define FPGA_LOW16_SHIFT 0
#define FPGA_HIGH16_MASK GENMASK(31, 16)
#define FPGA_HIGH16_SHIFT 16
#define FPGA_BRIGHTNESS_VALUE_MASK GENMASK(15, 0)
#define FPGA_BRIGHTNESS_VALUE_SHIFT 0
#define FPGA_BRIGHTNESS_MODE_EN BIT(16)
#define FPGA_CONTRAST_VALUE_MASK GENMASK(15, 0)
#define FPGA_CONTRAST_VALUE_SHIFT 0
#define FPGA_CONTRAST_MODE_EN BIT(16)
#define FPGA_CURSOR_X_MASK GENMASK(15, 0)
#define FPGA_CURSOR_X_SHIFT 0
#define FPGA_CURSOR_Y_MASK GENMASK(31, 16)
#define FPGA_CURSOR_Y_SHIFT 16
#define FPGA_CURSOR_MODE_EN BIT(0)
#define FPGA_CURSOR_SET_EN BIT(1)
...
class AxiLiteOut
{
public:
AxiLiteOut(u32 phy_base, u32 size) {
regs_.phy_base_ = phy_base;
regs_.total_size_ = size;
}
void set_brightness_mode(u8 value) {
regs_.set_bit_value(0, FPGA_BRIGHTNESS_MODE_EN, value);
}
void set_brightness_value(u16 value) {
regs_.set_value(0, value, FPGA_BRIGHTNESS_VALUE_MASK, FPGA_BRIGHTNESS_VALUE_SHIFT);
}
void set_brightness_value(float value) {
u16 data = (u16)(value * 1024);
set_brightness_value(data);
}
void set_contrast_mode(u8 value) {
regs_.set_bit_value(1, FPGA_CONTRAST_MODE_EN, value);
}
void set_contrast_value(u16 value) {
regs_.set_value(1, value, FPGA_CONTRAST_VALUE_MASK, FPGA_CONTRAST_VALUE_SHIFT);
}
void set_cursor_mode(u8 value) {
regs_.set_bit_value(8, FPGA_CURSOR_MODE_EN, value);
}
void set_cursor_en(u8 value) {
regs_.set_bit_value(8, FPGA_CURSOR_SET_EN, value);
}
void set_cursor_x(u16 value) {
regs_.set_value(7, value, FPGA_CURSOR_X_MASK, FPGA_CURSOR_X_SHIFT);
}
void set_cursor_y(u16 value) {
regs_.set_value(7, value, FPGA_CURSOR_Y_MASK, FPGA_CURSOR_Y_SHIFT);
}
void set_over_info(u32* src, int len) {
for (int i = 0; i < len; i++)
{
u32 offset = 17 + i;
u32 value = src[i];
regs_.set_value(offset, value);
}
}
...
protected:
IoMem regs_;
};