diff --git a/sdk/bsp/include/i2c.h b/sdk/bsp/include/i2c.h index 07b9cd3..792dab4 100644 --- a/sdk/bsp/include/i2c.h +++ b/sdk/bsp/include/i2c.h @@ -43,8 +43,13 @@ void i2c0_stop(); #define I2C_CTRL_INT_PENDING_BIT 2 #define I2C_CTRL_MODE_BIT 3 #define I2C_CTRL_WRITE_BIT 4 -#define I2C_CTRL_ACK_BIT 5 -#define I2C_CTRL_ERROR_BIT 6 +#define I2C_CTRL_ERROR_BIT 5 +#define I2C_CTRL_SLAVE_WR_BIT 6 +#define I2C_CTRL_SLAVE_RDY_BIT 7 +#define I2C_CTRL_SLAVE_ADDR_MASK 0xff +#define I2C_CTRL_SLAVE_ADDR_OFFSET 8 +#define I2C_CTRL_SLAVE_ADDR_FIELD \ + ((bitfield_field32_t) { .mask = I2C_CTRL_SLAVE_ADDR_MASK, .index = I2C_CTRL_SLAVE_ADDR_OFFSET }) #define I2C_CTRL_CLK_DIV_MASK 0xffff #define I2C_CTRL_CLK_DIV_OFFSET 16 #define I2C_CTRL_CLK_DIV_FIELD \ @@ -66,13 +71,17 @@ void i2c0_stop(); #define I2C_MASTER_DATA_DATA_FIELD \ ((bitfield_field32_t) { .mask = I2C_MASTER_DATA_DATA_MASK, .index = I2C_MASTER_DATA_DATA_OFFSET }) -// I2C slave received data register -#define I2C_SLAVE_DATA_REG_OFFSET 0x8 -#define I2C_SLAVE_DATA_REG_RESVAL 0x0 -#define I2C_SLAVE_DATA_SLAVE_DATA_MASK 0xff -#define I2C_SLAVE_DATA_SLAVE_DATA_OFFSET 0 -#define I2C_SLAVE_DATA_SLAVE_DATA_FIELD \ - ((bitfield_field32_t) { .mask = I2C_SLAVE_DATA_SLAVE_DATA_MASK, .index = I2C_SLAVE_DATA_SLAVE_DATA_OFFSET }) +// I2C slave read or write address register +#define I2C_SLAVE_ADDR_REG_OFFSET 0x8 +#define I2C_SLAVE_ADDR_REG_RESVAL 0x0 + +// I2C slave write data register +#define I2C_SLAVE_WDATA_REG_OFFSET 0xc +#define I2C_SLAVE_WDATA_REG_RESVAL 0x0 + +// I2C slave read data register +#define I2C_SLAVE_RDATA_REG_OFFSET 0x10 +#define I2C_SLAVE_RDATA_REG_RESVAL 0x0 #ifdef __cplusplus } // extern "C" diff --git a/sdk/examples/i2c_master/.gitignore b/sdk/examples/i2c_master/.gitignore new file mode 100644 index 0000000..294f05e --- /dev/null +++ b/sdk/examples/i2c_master/.gitignore @@ -0,0 +1,8 @@ +# Object files +*.o +*.ko +*.obj +*.bin +*.dump +*.mem +i2c_master diff --git a/sdk/examples/i2c_master/Makefile b/sdk/examples/i2c_master/Makefile new file mode 100644 index 0000000..2ac36bb --- /dev/null +++ b/sdk/examples/i2c_master/Makefile @@ -0,0 +1,20 @@ +RISCV_ARCH := rv32im +RISCV_ABI := ilp32 +RISCV_MCMODEL := medlow + + +TARGET = i2c_master + + +#CFLAGS += -DSIMULATION +#CFLAGS += -O2 +#ASM_SRCS += +#LDFLAGS += +#INCLUDES += -I. + +C_SRCS := \ + main.c \ + + +BSP_DIR = ../../bsp +include ../../bsp/bsp.mk diff --git a/sdk/examples/i2c_master/README.md b/sdk/examples/i2c_master/README.md new file mode 100644 index 0000000..0f0cc1a --- /dev/null +++ b/sdk/examples/i2c_master/README.md @@ -0,0 +1 @@ +i2c_master例程。 \ No newline at end of file diff --git a/sdk/examples/i2c_master/main.c b/sdk/examples/i2c_master/main.c new file mode 100644 index 0000000..6f0725b --- /dev/null +++ b/sdk/examples/i2c_master/main.c @@ -0,0 +1,72 @@ +#include + +#include "../../bsp/include/uart.h" +#include "../../bsp/include/i2c.h" +#include "../../bsp/include/xprintf.h" +#include "../../bsp/include/utils.h" +#include "../../bsp/include/rvic.h" + + +#define SLAVE_ADDR (0xA0) + +static volatile uint8_t i2c_done; + +static void i2c_master_write(uint8_t addr, uint8_t data) +{ + i2c_done = 0; + i2c0_master_set_write(1); + i2c0_master_set_info(SLAVE_ADDR, addr, data); + i2c0_start(); + + while (!i2c_done); +} + +static uint8_t i2c_master_read(uint8_t addr) +{ + i2c_done = 0; + i2c0_master_set_write(0); + i2c0_master_set_info(SLAVE_ADDR, addr, 0); + i2c0_start(); + + while (!i2c_done); + + return (i2c0_master_get_data()); +} + +int main() +{ + uint8_t data, i; + + uart0_init(uart0_putc); + + i2c0_set_clk(0x7D); // 200KHZ + i2c0_set_mode(I2C_MODE_MASTER); + i2c0_set_interrupt_enable(1); + + rvic_set_irq_prio_level(RVIC_INT_ID_4, 1); + rvic_irq_enable(RVIC_INT_ID_4); + global_irq_enable(); + + // 写 + for (i = 0; i < 10; i++) { + i2c_master_write(i, i); + xprintf("write[%d] = 0x%x\n", i, i); + busy_wait(100 * 1000); + } + + // 读 + for (i = 0; i < 10; i++) { + data = i2c_master_read(i); + xprintf("read[%d] = 0x%x\n", i, data); + } + + while (1); +} + +void i2c0_irq_handler() +{ + i2c_done = 1; + + i2c0_clear_irq_pending(); + rvic_clear_irq_pending(RVIC_INT_ID_4); +}