Commit bca88616 authored by Vincent van Beveren's avatar Vincent van Beveren

build lm32 implementation (not finished yet)

Signed-off-by: Vincent van Beveren's avatarVincent van Beveren <v.van.beveren@nikhef.nl>
parent be8bd102
**/*.o
**/*.a
doc/html
doc/latex
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
<storageModule moduleId="org.eclipse.cdt.core.settings">
<cconfiguration id="cdt.managedbuild.toolchain.gnu.cross.base.1715085401">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.toolchain.gnu.cross.base.1715085401" moduleId="org.eclipse.cdt.core.settings" name="Default">
<externalSettings/>
<extensions>
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactName="${ProjName}" buildProperties="" description="" id="cdt.managedbuild.toolchain.gnu.cross.base.1715085401" name="Default" parent="org.eclipse.cdt.build.core.emptycfg">
<folderInfo id="cdt.managedbuild.toolchain.gnu.cross.base.1715085401.2129613306" name="/" resourcePath="">
<toolChain id="cdt.managedbuild.toolchain.gnu.cross.base.543226004" name="Cross GCC" superClass="cdt.managedbuild.toolchain.gnu.cross.base">
<option id="cdt.managedbuild.option.gnu.cross.prefix.2083903150" name="Prefix" superClass="cdt.managedbuild.option.gnu.cross.prefix"/>
<option id="cdt.managedbuild.option.gnu.cross.path.927128670" name="Path" superClass="cdt.managedbuild.option.gnu.cross.path"/>
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="cdt.managedbuild.targetPlatform.gnu.cross.733130988" isAbstract="false" osList="all" superClass="cdt.managedbuild.targetPlatform.gnu.cross"/>
<builder id="cdt.managedbuild.builder.gnu.cross.1362464039" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="cdt.managedbuild.builder.gnu.cross"/>
<tool id="cdt.managedbuild.tool.gnu.cross.c.compiler.127428408" name="Cross GCC Compiler" superClass="cdt.managedbuild.tool.gnu.cross.c.compiler">
<option id="gnu.c.compiler.option.preprocessor.def.symbols.1605705687" name="Defined symbols (-D)" superClass="gnu.c.compiler.option.preprocessor.def.symbols" useByScannerDiscovery="false" valueType="definedSymbols">
<listOptionValue builtIn="false" value="SFP_WRITE_SUPPORT"/>
</option>
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.1058506932" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
</tool>
<tool id="cdt.managedbuild.tool.gnu.cross.cpp.compiler.73750744" name="Cross G++ Compiler" superClass="cdt.managedbuild.tool.gnu.cross.cpp.compiler">
<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1539050551" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
</tool>
<tool id="cdt.managedbuild.tool.gnu.cross.c.linker.967550631" name="Cross GCC Linker" superClass="cdt.managedbuild.tool.gnu.cross.c.linker"/>
<tool id="cdt.managedbuild.tool.gnu.cross.cpp.linker.250184423" name="Cross G++ Linker" superClass="cdt.managedbuild.tool.gnu.cross.cpp.linker">
<inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.1448353394" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
</tool>
<tool id="cdt.managedbuild.tool.gnu.cross.archiver.56032099" name="Cross GCC Archiver" superClass="cdt.managedbuild.tool.gnu.cross.archiver"/>
<tool id="cdt.managedbuild.tool.gnu.cross.assembler.732695470" name="Cross GCC Assembler" superClass="cdt.managedbuild.tool.gnu.cross.assembler">
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.436963226" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
</tool>
</toolChain>
</folderInfo>
<sourceEntries>
<entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="arch-wrpc-lm32"/>
<entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="inc"/>
<entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="src"/>
</sourceEntries>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="libsfp.null.2045100723" name="libsfp"/>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
<storageModule moduleId="refreshScope" versionNumber="2">
<configuration configurationName="Default">
<resource resourceType="PROJECT" workspacePath="/libsfp"/>
</configuration>
</storageModule>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.cross.base.1715085401;cdt.managedbuild.toolchain.gnu.cross.base.1715085401.2129613306;cdt.managedbuild.tool.gnu.cross.cpp.compiler.73750744;cdt.managedbuild.tool.gnu.cpp.compiler.input.1539050551">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.cross.base.1715085401;cdt.managedbuild.toolchain.gnu.cross.base.1715085401.2129613306;cdt.managedbuild.tool.gnu.cross.c.compiler.127428408;cdt.managedbuild.tool.gnu.c.compiler.input.1058506932">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
</cproject>
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>libsfp</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<triggers>clean,full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>org.eclipse.cdt.core.ccnature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
</natures>
</projectDescription>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project>
<configuration id="cdt.managedbuild.toolchain.gnu.cross.base.1715085401" name="Default">
<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
<provider class="org.eclipse.cdt.managedbuilder.internal.language.settings.providers.GCCBuiltinSpecsDetectorCygwin" console="false" env-hash="-339977209373872057" id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetectorCygwin" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings Cygwin" parameter="lm32-elf-gcc ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>
</extension>
</configuration>
</project>
This diff is collapsed.
eclipse.preferences.version=1
environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1715085401/append=true
environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1715085401/appendContributed=true
This source diff could not be displayed because it is too large. You can view the blob instead.
# Configure default architecutre and compiler
ARCH ?= wrpc-lm32
CROSS_COMPILE ?= lm32-elf-
# Cross-compilation tool-set
AS = $(CROSS_COMPILE)as
LD = $(CROSS_COMPILE)ld
CC = $(CROSS_COMPILE)gcc
CPP = $(CC) -E
AR = $(CROSS_COMPILE)ar
NM = $(CROSS_COMPILE)nm
STRIP = $(CROSS_COMPILE)strip
OBJCOPY = $(CROSS_COMPILE)objcopy
OBJDUMP = $(CROSS_COMPILE)objdump
.PHONY: all clean debug
# Target
TARGET = sfp
FULL_TARGET = lib$(TARGET).a
# include
INCLUDE_DIRS = inc arch-$(ARCH)
# CFLAGS to use. Both this Makefile (later) and app-makefile may grow CFLAGS
CFLAGS = $(USER_CFLAGS)
CFLAGS += -Wall -O2 -ggdb -fno-common -DSFP_WRITE_SUPPORT
CFLAGS += $(foreach includedir,$(INCLUDE_DIRS),-I$(includedir))
# Gather all source files in project
C_SRCS = $(wildcard src/*.c) $(wildcard arch-$(ARCH)/*.c)
C_OBJS = $(patsubst %.c, %.o, $(C_SRCS))
# The main target is the big object file.
all: debug $(FULL_TARGET)
%.o: %.c
echo "Compiling $< -> $@"
$(CC) $(CFLAGS) -c -o $@ "$<"
$(FULL_TARGET) : $(C_OBJS)
$(AR) r $@ $^
clean:
$(RM) $(C_OBJS) $(FULL_TARGET)
debug:
echo "C_SRCS=$(C_SRCS)"
echo "C_OBJS=$(C_OBJS)"
echo "CFLAGS=$(CFLAGS)"
\ No newline at end of file
/*
* wrpc_config.h
*
* Created on: 23 okt. 2017
* Author: vincentb
*/
#ifndef WRPC_CONFIG_H_
#define WRPC_CONFIG_H_
/**
* WRPC configuration file
*/
// ===========================================================================
// GPIO Configuration
// ===========================================================================
#define WB_GPIO_BASE_ADDRESS 0x00000000
#define WB_GPIO_PORT_COUNT 32
// ===========================================================================
// I2C Configuration
// ===========================================================================
#define WB_I2C_COUNT 3
// WR_I2C_MASTERS is a list of WR_I2C_MASTER items defiend as:
// WR_I2C_MASTER(INDEX, NAME, ADDRESS)
// Where:
// INDEX runs from 0 to WB_I2C_COUNT - 1
// NAME is the device name (e.g "I2C0", "I2C1", etc..)
// ADDRESS is the base address of the I2C device
#define WR_I2C_MASTERS \
WR_I2C_MASTER(0, "I2C0", 0x00000000) \
WR_I2C_MASTER(1, "I2C1", 0x00000000) \
WR_I2C_MASTER(2, "I2C2", 0x00000000)
// ===========================================================================
// SFP Configuration
// ===========================================================================
#define SFP_COUNT 1
// SFP_SLOTS: Defines the SFP slots
// SFP_SLOT(I2C_IDX, NAME, MOD_PRESENT_GPIO, RX_LOSS_GPIO, TX_FAULT_GPIO)
// Where:
// SFP_IDX Index of the I2C device
// NAME Human readable name of this slot
// MOD_PRESENT_GPIO Module present GPIO, or -1 if it does not exist
// RX_LOSS_GPIO RX loss GPIO, or -1 if it does not exist
// TX_FAULT_GPIO TX fault GPIO, or -1 if it does not exist
#define SFP_SLOTS \
SFP_SLOT(0, "SFP0", -1, -1, -1)
#endif /* WRPC_CONFIG_H_ */
/*
* wrpc_gpio.c
*
* Created on: 23 okt. 2017
* Author: vincentb
*/
#include "sfpgpio.h"
#include "wrpc_config.h"
SFP_STUB sfp_status_t gpio_set_pinmode(sfp_gpio_pin_t pin, gpio_pinmode_t mode)
{
if (pin >= WB_GPIO_PORT_COUNT) return SFP_STATUS_INVALID;
// TODO
return SFP_STATUS_OK;
}
SFP_STUB bool gpio_get_level(sfp_gpio_pin_t pin)
{
if (pin >= WB_GPIO_PORT_COUNT) return false;
// TODO
return false;
}
SFP_STUB void gpio_set_level(sfp_gpio_pin_t pin, bool level)
{
if (pin >= WB_GPIO_PORT_COUNT) return;
// TODO
}
/*
* wrpc_i2c.c
*
* Created on: 23 okt. 2017
* Author: vincentb
*/
#include "sfpi2c_prov.h"
#include "wrpc_config.h"
sfp_status_t sfp_i2c_mtx_lm32wb(struct sfp_prov_i2c_s * pi2c, sfp_i2c_mtx_op_t oper)
{
// for now, locking and unlocking is not suported.
return SFP_STATUS_OK;
}
sfp_status_t sfp_i2c_trx_lm32wb(struct sfp_prov_i2c_s * pi2c, uint8_t adr, sfp_i2c_trx_t * trx)
{
// TODO execute transaction
return SFP_STATUS_OK;
}
#define WR_I2C_MASTER(IDX, NAME, OFFSET) \
{ \
.pub = { .name = NAME }, \
.trx = sfp_i2c_trx_lm32wb, \
.mtx = sfp_i2c_mtx_lm32wb, \
.user0 = {.v_ptr = ((void *)OFFSET) }, \
.user1 = {.u32 = IDX }, \
},
static sfp_prov_i2c_t _i2c_devs[WB_I2C_COUNT] = {
WR_I2C_MASTERS
};
#undef WR_I2C_MASTER
SFP_STUB unsigned int sfp_i2c_count()
{
return WB_I2C_COUNT;
}
SFP_STUB sfp_status_t sfp_i2c_get(unsigned int idx, sfp_i2c_t ** i2cdev)
{
if (idx >= WB_I2C_COUNT) return SFP_STATUS_INVALID;
*i2cdev = &_i2c_devs[idx].pub;
return SFP_STATUS_OK;
}
/*
* wrpc_sfpmod.c
*
* Created on: 23 okt. 2017
* Author: vincentb
*/
#include "sfpmod_prov.h"
#include "wrpc_config.h"
/*
typedef struct sfp_prov_mod_s {
sfp_mod_t pub; //!< Public SFP module structure
sfp_mod_ee_rd_f ee_rd; //!< Eeprom read
sfp_mod_ee_wd_f ee_wr; //!< Eeprom write
sfp_mod_sts_f sts; //!< Get status
void * user; //!< Custom data object.
} sfp_prov_mod_t;
typedef struct sfp_comp_mod_s {
sfp_prov_mod_t prov; //!< Provider interface
sfp_i2c_t * i2c; //!< I2C bus pointer
sfp_mux_op_t mux0; //!< Mux level 0, if any
sfp_mux_op_t mux1; //!< Mux level 1, if any
sfp_gpio_pin_t tx_fault; //!< Tx fault GPIO, or SFP_GPIO_NONE
sfp_gpio_pin_t rx_loss; //!< Rx loss GPIO, or SFP_GPIO_NONE
sfp_gpio_pin_t mod_prsnt; //!< Module present GPIO, or SFP_GPIO_NONE
sfp_gpio_pin_t reserved; //!< Reserved
} sfp_comp_mod_t;
*/
#define SFP_SLOT(I2C_IDX, NAME, MOD_PRESENT_GPIO, RX_LOSS_GPIO, TX_FAULT_GPIO) \
{ \
.prov = { \
.pub = { .name = NAME }, \
.ee_rd = sfp_comp_mod_ee_rd, \
.ee_wr = sfp_comp_mod_ee_wr, \
.sts = sfp_comp_mod_sts, \
.user = { .u32 = I2C_IDX } \
}, \
.i2c = NULL, /* lazy init */ \
.mux0 = { .val = 0 }, \
.mux1 = { .val = 0 }, \
.tx_fault = TX_FAULT_GPIO, \
.rx_loss = RX_LOSS_GPIO, \
.mod_prsnt = MOD_PRESENT_GPIO \
},
// we'll need to initialize this dynamically
static sfp_comp_mod_t _modules[SFP_COUNT] = {
SFP_SLOTS
};
#undef SFP_SLOT
SFP_STUB unsigned int sfp_mod_count()
{
return SFP_COUNT;
}
/*!
* \brief Get the reference to a module at the specified index position.
*
* \param idx The index position, 0..sfp_mod_count() - 1 .
* \param module A pointer pointer which will be set to provider module
*
* \return A SFP_STATUS_* value. See \link sfp_status_t \endlink
*/
SFP_STUB sfp_status_t sfp_mod_get(unsigned int idx, sfp_mod_t ** module)
{
if (idx >= SFP_COUNT) return SFP_STATUS_INVALID;
// lazy init of I2C, as we can not call this at initialization time
if (_modules[idx].i2c == NULL)
{
sfp_i2c_t * i2c;
if (sfp_i2c_get(_modules[idx].prov.user.u32, &i2c) != SFP_STATUS_OK)
return SFP_STATUS_MODULE_CONFIG_ERROR;
_modules[idx].i2c = i2c;
}
*module = &_modules[idx].prov.pub;
return SFP_STATUS_OK;
}
/*!
* \file sfpcommon.h
*
* \brief Common types and structures
*
* \author Vincent van Beveren v.van.beveren[at]nikhef.nl
* \date 4 July 2017
*/
#ifndef SFPCOMMON_H_
#define SFPCOMMON_H_
#include <stdint.h>
//! Marker to indicate the function needs to be implemented by the architecture.
#define SFP_STUB
/*!
* \brief Return status
*/
typedef enum sfp_status_e {
SFP_STATUS_OK,
SFP_STATUS_ERROR, //!< Generic unspecifeid error
SFP_STATUS_INVALID, //!< Resource is invalid
SFP_STATUS_NOT_SUPPORTED, //!< Not supported operation
SFP_STATUS_MODULE_CONFIG_ERROR, //!< Some part of the module configuration is invalid
SFP_STATUS_RESOURCE_IN_USE //!< Can't execute operation, resource in use
} sfp_status_t;
/**
* Generic variant type object.
*/
typedef union sfp_variant_u {
void * v_ptr;
uint32_t u32;
} sfp_variant_t;
#endif /* SFPCOMMON_H_ */
/*!
* \file sfpgpio.h
*
* \brief Public GPIO header file
*
* \author Vincent van Beveren (v.van.beveren[at]nikhef.nl)
* \date 4 July 2017
*
* Currently there is no notion of a GPIO instance in this abstraction. Usually there is just one GPIO
* instance. Otherwise one should use the upper bits in the pin value to make the distinction.
*/
#ifndef SFPGPIO_H_
#define SFPGPIO_H_
#include "sfpcommon.h"
#include <stdint.h>
#include <stdbool.h>
/**
* Pin-mode configuration.
*/
typedef enum gpio_pinmode_e {
GPIO_PINMODE_INPUT,
GPIO_PINMODE_OUTPUT
} gpio_pinmode_t;
/**
* Definition of a GPIO pin
*/
typedef uint16_t sfp_gpio_pin_t;
/**
* PIN error.
*/
#define SFP_GPIO_NONE ((sfp_gpio_pin_t)0xFFFF)
/**
* Sets the pin mode.
*
* @param pin The pin
* @param mode The mode
*
*
* @retval SFP_STATUS_OK If all is Ok
* @retval SFP_STATUS_NOT_SUPPORTED If the the mode does not exist
* @retval SFP_STATUS_INVALID If the pin is does not exist.
*/
SFP_STUB sfp_status_t gpio_set_pinmode(sfp_gpio_pin_t pin, gpio_pinmode_t mode);
/**
* Get GPIO pin level.
*
* If this is an input, it is the level the pin reads.
* If this is an output, it is the level the pin was set on.
*
* If the pin does not exist, this returns false.
*
* @param pin The pin
*
* @retval true Pin level high
* @retval false Pin level low
*/
SFP_STUB bool gpio_get_level(sfp_gpio_pin_t pin);
/**
* Set GPIO pin level. Only useful for output.
*
* Function does nothing if pin does not exist.
*
* @param pin The pin
* @param level The level to set: true - high, false - low.
*/
SFP_STUB void gpio_set_level(sfp_gpio_pin_t pin, bool level);
#endif /* SFPGPIO_H_ */
/*!
* \file sfpi2c.h
*
* \brief User header file for I2C.
*
* \author Vincent van Beveren (v.van.beveren[at]nikhef.nl)
* \date 4 July 2017
*/
#ifndef SFPI2C_H_
#define SFPI2C_H_
#include "sfpcommon.h"
#include <stdint.h>
#include <stddef.h>
/*!
* \brief Generic I2C structure.
*/
typedef struct sfp_i2c_s {
const char * name; //!< I2C master name.
} sfp_i2c_t;
/*!
* I2C slave definition.
*/
typedef struct sfp_i2c_slave_s {
sfp_i2c_t * i2c; //!< I2C master device
uint8_t addr; //!< I2C slave address
} sfp_i2c_slave_t;
/*!
* \brief Define an I2C slave (I2C device + address)
*
* @param i2c I2C device
* @param addr Address
*/
static inline sfp_i2c_slave_t sfp_i2c_slave(sfp_i2c_t * i2c, uint8_t addr)
{
sfp_i2c_slave_t slave;
slave.i2c = i2c;
slave.addr = addr;
return slave;
}
/*!
* \brief Returns the number of I2C master devices.
*/
SFP_STUB unsigned int sfp_i2c_count();
/*!
* \brief Returns the I2C module at the given index.
*
* \param idx The index of the device to get range 0..sfp_i2c_count() - 1.
* \param i2cdev A pointer pointer to get to the I2C device structure.
*
* \return A SFP_STATUS_* value. See \link sfp_status_t \endlink.
*/
SFP_STUB sfp_status_t sfp_i2c_get(unsigned int idx, sfp_i2c_t ** i2cdev);
/*!
* \brief I2C mutex operation.
*/
typedef enum sfp_i2c_mtx_op_e {
SFP_I2C_MUX_LOCK, //!< Lock the I2C bus for usage by this module
SFP_I2C_MUX_UNLOCK //!< Unlock it.
} sfp_i2c_mtx_op_t;
/*!
* \brief Lock or unlock the mutex
*
* \param i2c The I2C master to lock or unlock
* \param The operation, one of SFP_I2C_MUX_*
*
* \return A SFP_STATUS_* value. See \link sfp_status_t \endlink.
*/
sfp_status_t sfp_i2c_mtx(sfp_i2c_t * i2c, sfp_i2c_mtx_op_t oper);
/**
* \brief I2C transaction structure.
*
* There are four types of operations:
*
* - WRITE - Write from buffer 0 to I2C bus.
* - READ - Read into buffer from I2C bus.
* - WRITE_READ - Write from the first buffer and read into the second
* - WRITE_WRITE - Write from the first buffer and write from the second.
* - EXISTS - For this operation no buffers need to be filled, just
* checks if its possible to read from this device.
*
* The first two operations can be use for simple, non registered chips like muxes or ADCs.
* The second two operations can be used for registered devices, in which the proper register or
* address must first be written. For example, reading 16 bytes from EEPROM address 0xBEEF can be
* done as follows:
*
* @code
* uint8_t addr[2] = { 0xBE, 0xEF };
* uint8_t data[16];
*
* sfp_i2c_trx_t trx = {
* I2C_TRX_OPER_WRITE_READ,
* {
* { addr, sizeof(addr) },
* { data, sizeof(data) }
* }
* }
*
* sfp_i2c_trx(I2C1, 0xAA, &trx);
* @endcode
*
*/
typedef struct sfp_i2c_trx_s {
enum {
I2C_TRX_OPER_READ, //!< Read into buf[0]
I2C_TRX_OPER_WRITE, //!< Write from buf[0]
I2C_TRX_OPER_WRITE_READ, //!< Write from buf[0] and read into buf[1]
I2C_TRX_OPER_WRITE_WRITE, //!< Write from buf[0] and write from buf[1]
I2C_TRX_OPER_EXISTS //!< Simple existence check by checking for an ACK on read. No buffers used.
} oper; //!< Operation(s) to perform.
struct {
uint8_t * ptr; //!< Pointer to buffer to read or fill
size_t len; //!< Length of buffer to read or fill
} buf[2]; //!< Two buffers
} sfp_i2c_trx_t;
/*!
*
* \brief Execute an I2C transaction.
*
* \see sfp_i2c_trx_t
*
* \param slave The I2C slave
* \param trx A pointer to a transaction object
*
* \return A SFP_STATUS_* value. See \link sfp_status_t \endlink.
*/
sfp_status_t sfp_i2c_trx(sfp_i2c_slave_t * slave, sfp_i2c_trx_t * trx);
/*!
* I2C memory device read with 8 bit address space.
*/
static inline sfp_status_t sfp_i2c_a8_rd(sfp_i2c_slave_t * slave, uint8_t reg, uint8_t * data, size_t count)
{
sfp_i2c_trx_t trx = {
I2C_TRX_OPER_WRITE_READ,
{
{&reg, 1 },
{data, count }
}
};
return sfp_i2c_trx(slave, &trx);
}
/**
* I2C memory device write with 8 bit address space.
*/
static inline sfp_status_t sfp_i2c_a8_wr(sfp_i2c_slave_t * slave, uint8_t reg, uint8_t * data, size_t count)
{
sfp_i2c_trx_t trx = {
I2C_TRX_OPER_WRITE_READ,
{
{ &reg, 1 },
{ data, count }
}
};
return sfp_i2c_trx(slave, &trx);
}
static inline sfp_status_t sfp_i2c_wr(sfp_i2c_slave_t * slave, uint8_t * data, size_t count)
{
sfp_i2c_trx_t trx = {
I2C_TRX_OPER_WRITE,
{
{ data, count }
}
};
return sfp_i2c_trx(slave, &trx);
}
#endif /* SFPI2C_H_ */
/*!
* \file sfpi2c_prov.h
*
* \brief Architecture providers implementors header file for I2C.
*
* \author Vincent van Beveren (v.van.beveren[at]nikhef.nl)
* \date 4 July 2017
*/
#ifndef SFPI2C_PROV_H_
#define SFPI2C_PROV_H_
#include "sfpi2c.h"
/*!
* Provider I2C structure.
*/
struct sfp_prov_i2c_s;
/*!
* Callback to implement for locking and unlocking the I2C bus.
*