mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-01-18 10:52:44 +01:00
319 lines
9.5 KiB
C
319 lines
9.5 KiB
C
/*
|
|
* 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.
|
|
*/
|
|
|
|
/**
|
|
* @defgroup drivers_periph_pio_i2c PIO I2C program
|
|
* @ingroup drivers_periph
|
|
* @brief PIO I2C program interface
|
|
*
|
|
* @experimental This API is experimental and in an early state -
|
|
* expect changes!
|
|
* @{
|
|
* @file
|
|
* @brief PIO I2C program interface
|
|
*
|
|
* @author Fabian Hüßler <fabian.huessler@ovgu.de>
|
|
*/
|
|
|
|
#ifndef PERIPH_PIO_I2C_H
|
|
#define PERIPH_PIO_I2C_H
|
|
|
|
#include "periph/i2c.h"
|
|
#include "periph/pio.h"
|
|
#include "mutex.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/**
|
|
* @brief PIO I2C descriptor type compatible with @ref i2c_t
|
|
*/
|
|
typedef i2c_t pio_i2c_t;
|
|
|
|
/**
|
|
* @brief PIO I2C program type
|
|
*/
|
|
typedef struct pio_program_i2c {
|
|
pio_program_t base; /**< PIO base program */
|
|
unsigned ref_mask; /**< Mask of referencing PIO state machines */
|
|
} pio_program_i2c_t;
|
|
|
|
/**
|
|
* @brief PIO I2C emulated bus type
|
|
*/
|
|
typedef struct pio_i2c_bus {
|
|
pio_t pio; /**< PIO index */
|
|
pio_sm_t sm; /**< State machine index */
|
|
mutex_t mtx; /**< Mutex to protect the bus from concurrent accesses */
|
|
} pio_i2c_bus_t;
|
|
|
|
/**
|
|
* @brief Get access to a PIO I2C instance configured with PIO_I2C_CONFIG
|
|
*
|
|
* @param[in] id PIO I2C ID
|
|
*
|
|
* @return PIO I2C objects
|
|
*/
|
|
pio_i2c_bus_t *pio_i2c_get(pio_i2c_t id);
|
|
|
|
/**
|
|
* @brief Query the number of PIO I2C instances configured with PIO_I2C_CONFIG
|
|
*
|
|
* @return Number of PIO I2C instances
|
|
*/
|
|
unsigned pio_i2c_numof(void);
|
|
|
|
/**
|
|
* @brief Get const I2C program reference
|
|
*
|
|
* @param[in] pio PIO index
|
|
*
|
|
* @return PIO I2C program allocated to PIO @p pio
|
|
*/
|
|
const pio_program_i2c_t *pio_i2c_get_program(pio_t pio);
|
|
|
|
/**
|
|
* @brief Create, allocate, and write a PIO I2C program
|
|
*
|
|
* This function does nothing if the program is already
|
|
* created, allocated, and written.
|
|
*
|
|
* @param[in] pio PIO index
|
|
*
|
|
* @return Success: 0
|
|
* Failure: != 0
|
|
*/
|
|
int pio_i2c_init_program(pio_t pio);
|
|
|
|
/**
|
|
* @brief Free a PIO I2C program
|
|
*
|
|
* @param[in] pio PIO index
|
|
*/
|
|
void pio_i2c_deinit_program(pio_t pio);
|
|
|
|
/**
|
|
* @brief Acquire a PIO state machine of PIO @p pio to run the PIO I2C program
|
|
*
|
|
* @param[in] pio PIO index
|
|
* @param[out] i2c PIO I2C bus
|
|
*
|
|
* @return A valid state machine index or a negative number on error
|
|
*/
|
|
pio_sm_t pio_i2c_sm_lock(pio_t pio, pio_i2c_bus_t *i2c);
|
|
|
|
/**
|
|
* @brief Release a PIO state machine of PIO @p pio
|
|
*
|
|
* @param[in, out] i2c PIO I2C bus
|
|
*/
|
|
void pio_i2c_sm_unlock(pio_i2c_bus_t *i2c);
|
|
|
|
/**
|
|
* @brief Start PIO I2C programs configured with PIO_I2C_CONFIG
|
|
*
|
|
* @note No execution is started if
|
|
* "DISABLE_MODULE += pio_autostart_i2c" is set
|
|
*/
|
|
void pio_i2c_start_programs(void);
|
|
|
|
/**
|
|
* @brief Stop PIO I2C programs configured with PIO_I2C_CONFIG
|
|
*/
|
|
void pio_i2c_stop_programs(void);
|
|
|
|
/**
|
|
* @brief Write a PIO I2C program to instruction memory
|
|
*
|
|
* @param[in] pio PIO index
|
|
* @param[in, out] pro Allocated PIO I2C program
|
|
*
|
|
* @return Success: 0
|
|
* Failure: != 0
|
|
*/
|
|
int pio_i2c_write_program(pio_t pio, pio_program_i2c_t *pro);
|
|
|
|
/**
|
|
* @brief Setup a state machine to run the I2C program
|
|
*
|
|
* @pre The program @p pro must have been allocated.
|
|
*
|
|
* @param[out] bus PIO I2C bus
|
|
* @param[in] pro Shared program base
|
|
* @param[in] sda SDA pin
|
|
* @param[in] scl SCL pin
|
|
* @param[in] irq IRQ line, 0 or 1
|
|
*
|
|
* @return Success: 0
|
|
* Failure: != 0
|
|
*/
|
|
int pio_i2c_init(pio_i2c_bus_t *bus,
|
|
const pio_program_i2c_t *pro,
|
|
gpio_t sda, gpio_t scl, unsigned irq);
|
|
|
|
/**
|
|
* @brief Get exclusive access to the emulated I2C bus
|
|
*
|
|
* @param[in] bus PIO I2C bus
|
|
*/
|
|
void pio_i2c_acquire(pio_i2c_bus_t *bus);
|
|
|
|
/**
|
|
* @brief Release emulated I2C bus
|
|
*
|
|
* @param[in] bus PIO I2C bus
|
|
*/
|
|
void pio_i2c_release(pio_i2c_bus_t *bus);
|
|
|
|
/**
|
|
* @brief Emulate @ref i2c_read_regs
|
|
*
|
|
* @param[in] pio PIO index
|
|
* @param[in] sm PIO state machine index
|
|
* @param[in] addr 7-bit or 10-bit device address (right-aligned)
|
|
* @param[in] reg Register address to read from (8- or 16-bit right-aligned)
|
|
* @param[out] data Memory location to store received data
|
|
* @param[in] len The number of bytes to read into @p data
|
|
* @param[in] flags Optional flags (see @ref i2c_flags_t)
|
|
*
|
|
* @return Success: 0
|
|
* Failure: != 0
|
|
*/
|
|
int pio_i2c_read_regs(pio_t pio, pio_sm_t sm, uint16_t addr,
|
|
uint16_t reg, void *data, size_t len, uint8_t flags);
|
|
|
|
/**
|
|
* @brief Emulate @ref i2c_read_reg
|
|
*
|
|
* @param[in] pio PIO index
|
|
* @param[in] sm PIO state machine index
|
|
* @param[in] addr 7-bit or 10-bit device address (right-aligned)
|
|
* @param[in] reg Register address to read from (8- or 16-bit right-aligned)
|
|
* @param[out] data Memory location to store received data
|
|
* @param[in] flags Optional flags (see @ref i2c_flags_t)
|
|
*
|
|
* @return Success: 0
|
|
* Failure: != 0
|
|
*/
|
|
static inline int pio_i2c_read_reg(pio_t pio, pio_sm_t sm, uint16_t addr,
|
|
uint16_t reg, void *data, uint8_t flags)
|
|
{
|
|
return pio_i2c_read_regs(pio, sm, addr, reg, data, 1, flags);
|
|
}
|
|
|
|
/**
|
|
* @brief Emulate @ref i2c_read_bytes
|
|
*
|
|
* @param[in] pio PIO index
|
|
* @param[in] sm PIO state machine index
|
|
* @param[in] addr 7-bit or 10-bit device address (right-aligned)
|
|
* @param[out] data Memory location to store received data
|
|
* @param[in] len The number of bytes to read into @p data
|
|
* @param[in] flags Optional flags (see @ref i2c_flags_t)
|
|
*
|
|
* @return Success: 0
|
|
* Failure: != 0
|
|
*/
|
|
int pio_i2c_read_bytes(pio_t pio, pio_sm_t sm, uint16_t addr,
|
|
void *data, size_t len, uint8_t flags);
|
|
|
|
/**
|
|
* @brief Emulate @ref i2c_read_byte
|
|
*
|
|
* @param[in] pio PIO index
|
|
* @param[in] sm PIO state machine index
|
|
* @param[in] addr 7-bit or 10-bit device address (right-aligned)
|
|
* @param[out] data Memory location to store received data
|
|
* @param[in] flags Optional flags (see @ref i2c_flags_t)
|
|
*
|
|
* @return Success: 0
|
|
* Failure: != 0
|
|
*/
|
|
static inline int pio_i2c_read_byte(pio_t pio, pio_sm_t sm, uint16_t addr,
|
|
void *data, uint8_t flags)
|
|
{
|
|
return pio_i2c_read_bytes(pio, sm, addr, data, 1, flags);
|
|
}
|
|
|
|
/**
|
|
* @brief Emulate @ref i2c_write_bytes
|
|
*
|
|
* @param[in] pio PIO index
|
|
* @param[in] sm PIO state machine index
|
|
* @param[in] addr 7-bit or 10-bit device address (right-aligned)
|
|
* @param[in] data Array holding the bytes to write to the device
|
|
* @param[in] len The number of bytes to write
|
|
* @param[in] flags Optional flags (see @ref i2c_flags_t)
|
|
*
|
|
* @return Success: 0
|
|
* Failure: != 0
|
|
*/
|
|
int pio_i2c_write_bytes(pio_t pio, pio_sm_t sm, uint16_t addr,
|
|
const void *data, size_t len, uint8_t flags);
|
|
|
|
/**
|
|
* @brief Emulate @ref i2c_write_byte
|
|
*
|
|
* @param[in] pio PIO index
|
|
* @param[in] sm PIO state machine index
|
|
* @param[in] addr 7-bit or 10-bit device address (right-aligned)
|
|
* @param[in] data Byte to write to the device
|
|
* @param[in] flags Optional flags (see @ref i2c_flags_t)
|
|
*
|
|
* @return Success: 0
|
|
* Failure: != 0
|
|
*/
|
|
static inline int pio_i2c_write_byte(pio_t pio, pio_sm_t sm, uint16_t addr,
|
|
uint8_t data, uint8_t flags)
|
|
{
|
|
return pio_i2c_write_bytes(pio, sm, addr, &data, 1, flags);
|
|
}
|
|
|
|
/**
|
|
* @brief Emulate @ref i2c_write_regs
|
|
*
|
|
* @param[in] pio PIO index
|
|
* @param[in] sm PIO state machine index
|
|
* @param[in] addr 7-bit or 10-bit device address (right-aligned)
|
|
* @param[in] reg register address to read from (8- or 16-bit, right-aligned)
|
|
* @param[in] data Array holding the bytes to write to the device
|
|
* @param[in] len The number of bytes to write
|
|
* @param[in] flags Optional flags (see @ref i2c_flags_t)
|
|
*
|
|
* @return Success: 0
|
|
* Failure: != 0
|
|
*/
|
|
int pio_i2c_write_regs(pio_t pio, pio_sm_t sm, uint16_t addr,
|
|
uint16_t reg, const void *data, size_t len, uint8_t flags);
|
|
|
|
/**
|
|
* @brief Emulate @ref i2c_write_reg
|
|
*
|
|
* @param[in] pio PIO index
|
|
* @param[in] sm PIO state machine index
|
|
* @param[in] addr 7-bit or 10-bit device address (right-aligned)
|
|
* @param[in] reg register address to read from (8- or 16-bit, right-aligned)
|
|
* @param[in] data Array holding the bytes to write to the device
|
|
* @param[in] flags Optional flags (see @ref i2c_flags_t)
|
|
*
|
|
* @return Success: 0
|
|
* Failure: != 0
|
|
*/
|
|
static inline int pio_i2c_write_reg(pio_t pio, pio_sm_t sm, uint16_t addr,
|
|
uint16_t reg, uint8_t data, uint8_t flags)
|
|
{
|
|
return pio_i2c_write_regs(pio, sm, addr, reg, &data, 1, flags);
|
|
}
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
#endif /* PERIPH_PIO_I2C_H */
|
|
/** @} */
|