Skip to content

Commit

Permalink
cpu/rpx0xx: Add PIO I2C implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
fabian18 committed Dec 19, 2021
1 parent 83af45e commit 442db5d
Show file tree
Hide file tree
Showing 15 changed files with 1,025 additions and 0 deletions.
1 change: 1 addition & 0 deletions boards/rpi-pico/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ config BOARD_RPI_PICO
bool
default y
select CPU_MODEL_RP2040
select HAS_PERIPH_I2C
select HAS_PERIPH_UART

select HAVE_SAUL_GPIO
1 change: 1 addition & 0 deletions boards/rpi-pico/Makefile.features
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
CPU := rpx0xx

# Put defined MCU peripherals here (in alphabetical order)
FEATURES_PROVIDED += periph_i2c
FEATURES_PROVIDED += periph_timer
FEATURES_PROVIDED += periph_uart
28 changes: 28 additions & 0 deletions boards/rpi-pico/include/periph_conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,16 @@ static const timer_conf_t timer_config[] = {

#define TIMER_NUMOF ARRAY_SIZE(timer_config)

/**
* @name I2C configuration
* @{
*/
/**
* @brief Number of I2C interfaces
*/
#define I2C_NUMOF 0
/** @} */

/**
* @name PIO configuration
* @{
Expand Down Expand Up @@ -107,6 +117,24 @@ static const pio_conf_t pio_config[] = {
#define PIO_SM_NUMOF 4 /**< Number of state machines per PIO */
#define PIO_INSTR_NUMOF 32 /**< Maximum number of instructions */
#define PIO_IRQ_NUMOF 8 /**< Number of interrupt flags per PIO */

#if defined(PIO_I2C_CONFIG) || defined(DOXYGEN)
/**
* @brief PIO I2C configuration
*
* PIO_I2C_CONFIG should be defined during the build process to fit
* the users pin selection.
*/
static const pio_i2c_conf_t pio_i2c_config[] = {
PIO_I2C_CONFIG
};
/**
* @brief Number of PIO I2C configurations
*/
#define PIO_I2C_NUMOF ARRAY_SIZE(pio_i2c_config)
#else
#define pio_i2c_config ((pio_i2c_conf_t *)NULL)
#endif
/** @} */

#ifdef __cplusplus
Expand Down
1 change: 1 addition & 0 deletions cpu/rpx0xx/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ config CPU_FAM_RPX0XX
select HAS_PERIPH_TIMER_PERIODIC
select HAS_PERIPH_UART_MODECFG
select HAS_PERIPH_UART_RECONFIGURE
select HAS_PIO_I2C

config CPU_FAM
default "RPX0XX" if CPU_FAM_RPX0XX
Expand Down
4 changes: 4 additions & 0 deletions cpu/rpx0xx/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,8 @@ MODULE = cpu

DIRS = $(RIOTCPU)/cortexm_common periph

ifneq (,$(filter pio_i2c,$(USEMODULE)))
DIRS += pio/i2c
endif

include $(RIOTBASE)/Makefile.base
5 changes: 5 additions & 0 deletions cpu/rpx0xx/Makefile.dep
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,9 @@ ifneq (,$(filter pio_%,$(USEMODULE)))
USEMODULE += periph_pio
endif

ifneq (,$(filter pio_i2c periph_i2c,$(FEATURES_USED)))
DEFAULT_MODULE += pio_autostart_i2c
USEMODULE += pio_i2c
endif

include $(RIOTCPU)/cortexm_common/Makefile.dep
1 change: 1 addition & 0 deletions cpu/rpx0xx/Makefile.features
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ FEATURES_PROVIDED += periph_pio
FEATURES_PROVIDED += periph_timer_periodic
FEATURES_PROVIDED += periph_uart_reconfigure
FEATURES_PROVIDED += periph_uart_modecfg
FEATURES_PROVIDED += pio_i2c
9 changes: 9 additions & 0 deletions cpu/rpx0xx/include/periph_cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,15 @@ typedef struct {
IRQn_Type irqn1; /**< PIO IRQ1 interrupt number */
} pio_conf_t;

/**
* @brief PIO I2C configuration type
*/
typedef struct {
gpio_t sda; /**< Pin to use as SDA pin */
gpio_t scl; /**< Pin to use as SCL pin */
unsigned irq; /**< PIO IRQ line to use */
} pio_i2c_conf_t;

/**
* @brief Get the PAD control register for the given GPIO pin as word
*
Expand Down
99 changes: 99 additions & 0 deletions cpu/rpx0xx/periph/i2c.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/*
* Copyright (C) 2021 Otto-von-Guericke Universität Magdeburg
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/

/**
* @ingroup cpu_rpx0xx
* @ingroup drivers_periph_i2c
* @{
*
* @file
* @brief Low-level I2C driver implementation
*
* @note This driver is so far only a dummy implementation
* to test the PIO I2C interface.
*
* @author Fabian Hüßler <fabian.huessler@ovgu.de>
* @}
*/

#include <errno.h>

#include "periph_conf.h"
#include "periph/i2c.h"
#include "periph/pio/i2c.h"

int i2c_acquire(i2c_t dev)
{
if (IS_USED(MODULE_PIO_I2C) && (int)dev >= I2C_NUMOF) {
pio_i2c_obj_t *i2c = pio_i2c_get(dev - I2C_NUMOF);
return i2c ? pio_i2c_acquire(&i2c->pro) : -EFAULT;
}
return -ENOTSUP;
}

void i2c_release(i2c_t dev)
{
if (IS_USED(MODULE_PIO_I2C) && (int)dev >= I2C_NUMOF) {
pio_i2c_obj_t *i2c = pio_i2c_get(dev - I2C_NUMOF);
if (i2c) {
pio_i2c_release(&i2c->pro);
}
}
}

int i2c_read_bytes(i2c_t dev, uint16_t addr, void *data,
size_t len, uint8_t flags)
{
if (IS_USED(MODULE_PIO_I2C) && (int)dev >= I2C_NUMOF) {
pio_i2c_obj_t *i2c = pio_i2c_get(dev - I2C_NUMOF);
return i2c ? pio_i2c_read_bytes(i2c->pio, i2c->sm, addr, data, len, flags) : -EFAULT;
}
return -ENOTSUP;
}

int i2c_read_regs(i2c_t dev, uint16_t addr, uint16_t reg,
void *data, size_t len, uint8_t flags)
{
if (IS_USED(MODULE_PIO_I2C) && (int)dev >= I2C_NUMOF) {
pio_i2c_obj_t *i2c = pio_i2c_get(dev - I2C_NUMOF);
return i2c ? pio_i2c_read_regs(i2c->pio, i2c->sm, addr, reg, data, len, flags) : -EFAULT;
}
return -ENOTSUP;
}

int i2c_read_reg(i2c_t dev, uint16_t addr, uint16_t reg,
void *data, uint8_t flags)
{
return i2c_read_regs(dev, addr, reg, data, 1, flags);
}

int i2c_write_bytes(i2c_t dev, uint16_t addr, const void *data,
size_t len, uint8_t flags)
{
if (IS_USED(MODULE_PIO_I2C) && (int)dev >= I2C_NUMOF) {
pio_i2c_obj_t *i2c = pio_i2c_get(dev - I2C_NUMOF);
return i2c ? pio_i2c_write_bytes(i2c->pio, i2c->sm, addr, data, len, flags) : -EFAULT;
}
return -ENOTSUP;
}

int i2c_write_regs(i2c_t dev, uint16_t addr, uint16_t reg,
const void *data, size_t len, uint8_t flags)
{
if (IS_USED(MODULE_PIO_I2C) && (int)dev >= I2C_NUMOF) {
pio_i2c_obj_t *i2c = pio_i2c_get(dev - I2C_NUMOF);
return i2c ? pio_i2c_write_regs(i2c->pio, i2c->sm, addr, reg, data, len, flags) : -EFAULT;
}
return -ENOTSUP;
}

int i2c_write_reg(i2c_t dev, uint16_t addr, uint16_t reg,
uint8_t data, uint8_t flags)
{
return i2c_write_regs(dev, addr, reg, &data, 1, flags);
}
5 changes: 5 additions & 0 deletions cpu/rpx0xx/periph/pio.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "periph_cpu.h"
#include "io_reg.h"
#include "pio/pio.h"
#include "periph/pio/i2c.h"
#define ENABLE_DEBUG 0
#include "debug.h"

Expand Down Expand Up @@ -132,6 +133,10 @@ void pio_init(pio_t pio)

void pio_start_programs(void)
{
if (IS_USED(MODULE_PIO_AUTOSTART_I2C)) {
pio_i2c_init_programs();
pio_i2c_start_programs();
}
}

pio_sm_t pio_sm_lock(pio_t pio)
Expand Down
11 changes: 11 additions & 0 deletions cpu/rpx0xx/pio/i2c/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
MODULE = pio_i2c

include $(RIOTBASE)/Makefile.base

i2c.c: i2c.hex.pio.h i2c_set_scl_sda.hex.pio.h

i2c.hex.pio.h: i2c.pio
$(Q) $(RIOTCPU)/$(CPU)/dist/pioasm.bash $< $@

i2c_set_scl_sda.hex.pio.h: i2c_set_scl_sda.pio
$(Q) $(RIOTCPU)/$(CPU)/dist/pioasm.bash $< $@
Loading

0 comments on commit 442db5d

Please sign in to comment.