这里我只放代码,在Diamond里添加RD1046里面的Verlag代码,通过线来连接(slave_passthru),具体代码如下:
在Diamond中需要添加:
wire i2c0clk,i2c0rst,i2c0slv_strb,i2c0slv_cyc,i2c0slv_ack,i2c0slv_we,i2c0intr_active_high;
wire [7:0] i2c0slv_master_data,i2c0slv_slave_data;
wire [31:0] i2c0slv_adr;
lm8_sys lm8_sys_inst
(
.slave_passthru_i2c0clk(i2c0clk)
, .slave_passthru_i2c0rst(i2c0rst)
, .slave_passthru_i2c0slv_adr(i2c0slv_adr)
, .slave_passthru_i2c0slv_master_data(i2c0slv_master_data)
, .slave_passthru_i2c0slv_slave_data(i2c0slv_slave_data)
, .slave_passthru_i2c0slv_strb(i2c0slv_strb)
, .slave_passthru_i2c0slv_cyc(i2c0slv_cyc)
, .slave_passthru_i2c0slv_ack(i2c0slv_ack)
, .slave_passthru_i2c0slv_err()
, .slave_passthru_i2c0slv_rty()
, .slave_passthru_i2c0slv_sel()
, .slave_passthru_i2c0slv_we(i2c0slv_we)
, .slave_passthru_i2c0slv_bte()
, .slave_passthru_i2c0slv_cti()
, .slave_passthru_i2c0slv_lock()
, .slave_passthru_i2c0intr_active_high(i2c0intr_active_high)
);
i2c_master_wb_top i2c_master_inst(
.wb_clk_i(i2c0clk),
.wb_rst_i(i2c0rst),
.arst_i(n_reset_27_domain),
.wb_adr_i(i2c0slv_adr[2:0]),
.wb_dat_i(i2c0slv_master_data),
.wb_dat_o(i2c0slv_slave_data),
.wb_we_i(i2c0slv_we),
.wb_stb_i(i2c0slv_strb),
.wb_cyc_i(i2c0slv_cyc),
.wb_ack_o(i2c0slv_ack),
.wb_inta_o(i2c0intr_active_high),
.scl(i2c_scl),
.sda(i2c_sda)
);
然后转回LMS中,这里我根据文档来写的一个函数,是可用来做i2c读写:
void WriteMasterI2c(MicoPassthruCtx_t *ctx, unsigned char address, unsigned char reg8H, unsigned char reg8L, unsigned char *data,unsigned char len){
unsigned char ret = 0xff;
char i;
unsigned char add = address + 0x00;//7位地址+读写位凑8位(写)
REG_WRITE(ctx->base, TXR, add);//设置TXR寄存器,写从设备地址
REG_WRITE(ctx->base, CR, 0x90);//发送地址
REG_READ(ctx->base, SR, ret);//读取SR状态寄存器
//取SR[1]是否为1,为1则进行下去
while((ret>>1)&0x1){
REG_READ(ctx->base, SR, ret);//读取SR状态寄存器
}
ret = 0xff; //清零
REG_WRITE(ctx->base, TXR, reg8H);//设置TXR寄存器,写从设备的寄存器
REG_WRITE(ctx->base, CR, 0x10);//发送寄存器
while(((ret>>1)&0x1)){
REG_READ(ctx->base, SR, ret);//读取SR状态寄存器
}
ret = 0xff; //清零
REG_WRITE(ctx->base, TXR, reg8L);//设置TXR寄存器,写从设备的寄存器
REG_WRITE(ctx->base, CR, 0x10);//发送寄存器
while((ret>>1)&0x1){
REG_READ(ctx->base, SR, ret);//读取SR状态寄存器
}
for(i = 0 ; i < len-1 ; i++){
ret = 0xff; //清零
REG_WRITE(ctx->base, TXR, data[i]);//设置TXR寄存器,写从设备的数据
REG_WRITE(ctx->base, CR, 0x10);//发送数据
while(((ret>>1)&0x1)){
REG_READ(ctx->base, SR, ret);//读取SR状态寄存器
}
}
ret = 0xff; //清零
REG_WRITE(ctx->base, TXR, (data[len-1]));//用数据的最后一个字节设置TXR
REG_WRITE(ctx->base, CR, 0x50);//以使WRITE能够发送数据的最后一个字节,然后发出STOP命令
while(((ret>>1)&0x1)){
REG_READ(ctx->base, SR, ret);//读取SR状态寄存器
}
return ;
}
void ReadMasterI2c(MicoPassthruCtx_t *ctx, unsigned char address, unsigned char reg8H, unsigned char reg8L, unsigned char *data, unsigned char len){
unsigned char ret = 0xff;
//char data[4];
unsigned char i;
unsigned char add = address + 0x00;//7位地址+读写位凑8位(写)
REG_WRITE(ctx->base, TXR, add);//设置TXR寄存器,写从设备地址
REG_WRITE(ctx->base, CR, 0x90);//发送地址
//取SR[1]是否为1,为1则进行下去
while(((ret>>1)&0x1)){
REG_READ(ctx->base, SR, ret);//读取SR状态寄存器
}
ret = 0xff; //清零
REG_WRITE(ctx->base, TXR, reg8H);//设置TXR寄存器,写从设备的寄存器
REG_WRITE(ctx->base, CR, 0x10);//发送寄存器
while(((ret>>1)&0x1)){
REG_READ(ctx->base, SR, ret);//读取SR状态寄存器
}
ret = 0xff; //清零
REG_WRITE(ctx->base, TXR, reg8L);//设置TXR寄存器,写从设备的寄存器
REG_WRITE(ctx->base, CR, 0x10);//发送寄存器
while(((ret>>1)&0x1)){
REG_READ(ctx->base, SR, ret);//读取SR状态寄存器
}
ret = 0xff; //清零
add = address + 0x01;//7位地址+读写位凑8位(读)
REG_WRITE(ctx->base, TXR, add);//设置TXR寄存器,写从设备地址
REG_WRITE(ctx->base, CR, 0x90);//发送地址
while(((ret>>1)&0x1)){
REG_READ(ctx->base, SR, ret);//读取SR状态寄存器
}
for(i = 0 ; i < len-1; i++){
ret = 0xff; //清零
REG_WRITE(ctx->base, CR, 0x20);//发出ACK命令。这样可以从从设备读取数据
while(((ret>>1)&0x1)){
REG_READ(ctx->base, SR, ret);//读取SR状态寄存器
}
REG_READ(ctx->base, RXR, data[i]);//读取接收寄存器的数据
}
ret = 0xff; //清零
REG_WRITE(ctx->base, CR, 0x28);
while(((ret>>1)&0x1)){
REG_READ(ctx->base, SR, ret);//读取SR状态寄存器
}
REG_READ(ctx->base, RXR, data[len-1]);//这将读取数据的最后一个字节,然后发出NACK
return ;
}
不过这个仅仅是可以用的阶段,但想更好还需要各位大佬去优化,已经仿真过亲测可用。