diff --git a/chipflow_lib/software/drivers/i2c.c b/chipflow_lib/software/drivers/i2c.c new file mode 100644 index 00000000..2e1bd2ee --- /dev/null +++ b/chipflow_lib/software/drivers/i2c.c @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ +#include "i2c.h" + +void i2c_init(volatile i2c_regs_t *i2c, uint32_t divider) { + i2c->divider = divider; +} + +void i2c_start(volatile i2c_regs_t *i2c) { + i2c->action = (1<<1); + while (i2c->status & 0x1) + ; +} + +int i2c_write(volatile i2c_regs_t *i2c, uint8_t data) { + i2c->send_data = data; + while (i2c->status & 0x1) + ; + return (i2c->status & 0x2) != 0; // check ACK +} + +uint8_t i2c_read(volatile i2c_regs_t *i2c) { + i2c->action = (1<<3); + while (i2c->status & 0x1) + ; + return i2c->receive_data; +} + +void i2c_stop(volatile i2c_regs_t *i2c) { + i2c->action = (1<<2); + while (i2c->status & 0x1) + ; +} diff --git a/chipflow_lib/software/drivers/i2c.h b/chipflow_lib/software/drivers/i2c.h new file mode 100644 index 00000000..3f708650 --- /dev/null +++ b/chipflow_lib/software/drivers/i2c.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ +#ifndef I2C_H +#define I2C_H + +#include + +typedef struct { + uint32_t divider; + uint32_t action; + uint32_t send_data; + uint32_t receive_data; + uint32_t status; +} i2c_regs_t; + +void i2c_init(volatile i2c_regs_t *i2c, uint32_t divider); +void i2c_start(volatile i2c_regs_t *i2c); +int i2c_write(volatile i2c_regs_t *i2c, uint8_t data); +uint8_t i2c_read(volatile i2c_regs_t *i2c); +void i2c_stop(volatile i2c_regs_t *i2c); + +#endif diff --git a/chipflow_lib/software/drivers/spi.c b/chipflow_lib/software/drivers/spi.c new file mode 100644 index 00000000..32667b2e --- /dev/null +++ b/chipflow_lib/software/drivers/spi.c @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ +#include "spi.h" + +void spi_init(volatile spi_regs_t *spi, uint32_t divider) { + spi->divider = divider; + spi->config = 0x02; // CS=0, SCK_EDGE=1, SCK_IDLE=0 +} + +uint32_t spi_xfer(volatile spi_regs_t *spi, uint32_t data, uint32_t width, bool deselect) { + spi->config = ((width - 1) << 3) | 0x06; // CS=1, SCK_EDGE=1, SCK_IDLE=0 + spi->send_data = data << (32U - width); + while (!(spi->status & 0x1)) // wait for rx full + ; + if (deselect) { + spi->config = ((width - 1) << 3) | 0x02; // CS=0, SCK_EDGE=1, SCK_IDLE=0 + } + return spi->receive_data; +} diff --git a/chipflow_lib/software/drivers/spi.h b/chipflow_lib/software/drivers/spi.h new file mode 100644 index 00000000..a4f4836e --- /dev/null +++ b/chipflow_lib/software/drivers/spi.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ +#ifndef SPI_H +#define SPI_H + +#include +#include + +typedef struct { + uint32_t config; + uint32_t divider; + uint32_t send_data; + uint32_t receive_data; + uint32_t status; +} spi_regs_t; + +void spi_init(volatile spi_regs_t *spi, uint32_t divider); +uint32_t spi_xfer(volatile spi_regs_t *spi, uint32_t data, uint32_t width, bool deselect); + +#endif