Lattice Mico8通过RD1046写i2c master读写操作

这里我只放代码,在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 ;
}

不过这个仅仅是可以用的阶段,但想更好还需要各位大佬去优化,已经仿真过亲测可用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
开源IP核I2C仿真是通过使用开源软件和硬件进行I2C协议的仿真模拟。I2C(Inter-Integrated Circuit)是一种串行通信协议,常用于各种电子设备之间的通信。开源IP核是指基于开源许可的可重用的硬件模块,可以在FPGA(Field-Programmable Gate Array)等可编程逻辑器件中使用。通过仿真模拟,我们可以验证I2C通信的正确性、稳定性和性能。 为了进行开源IP核I2C仿真,我们可以使用一些开源软件和硬件平台。例如,我们可以使用Verilog或VHDL这样的硬件描述语言编开源的IP核代码,并使用开源的EDA(Electronic Design Automation)软件,如Yosys、Icarus Verilog和GTKWave进行仿真和波形分析。 在仿真过程中,我们可以模拟各种I2C设备的通信场景,包括主设备和从设备之间的数据传输和控制。我们可以设置时钟频率、数据帧大小、地址和传输模式等参数,以验证IP核的功能和性能是否符合规范。 另外,我们还可以使用开源硬件平台来验证IP核的功能。例如,我们可以将IP核代码加载到开源FPGA板上,如Lattice ICE40或Xilinx Spartan系列,然后在硬件级别模拟I2C通信。这样可以更加真实地模拟I2C设备之间的通信,同时也可以验证IP核在实际硬件环境中的正确性和稳定性。 总的来说,开源IP核I2C仿真是一种使用开源软件和硬件进行I2C通信模拟和验证的方法,可以帮助我们更好地理解和优化I2C通信,提高系统的可靠性和性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

smile_5me

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值