aboutsummaryrefslogtreecommitdiff
path: root/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon
diff options
context:
space:
mode:
authorTrygve Laugstøl <trygvis@inamo.no>2018-08-23 17:08:59 +0200
committerTrygve Laugstøl <trygvis@inamo.no>2018-08-23 17:12:21 +0200
commit3061ecca3d0fdfb87dabbf5f63c9e06c2a30f53a (patch)
treeab49cc16ed0b853452c5c2ed2d3042416d628986 /thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon
downloadiot-sensors-master.tar.gz
iot-sensors-master.tar.bz2
iot-sensors-master.tar.xz
iot-sensors-master.zip
o Initial import.HEADmaster
Diffstat (limited to 'thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon')
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/include/Datatypes.h122
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/include/ifx_i2c.h90
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/include/ifx_i2c_config.h296
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/include/ifx_i2c_data_link_layer.h103
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/include/ifx_i2c_physical_layer.h110
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/include/ifx_i2c_transport_layer.h84
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/include/optiga_comms.h90
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/include/pal.h60
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/include/pal_gpio.h84
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/include/pal_i2c.h92
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/include/pal_ifx_i2c_config.h49
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/include/pal_os_event.h61
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/include/pal_os_timer.h76
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/include/pal_socket.h182
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/optiga_comms/ifx_i2c/ifx_i2c.c419
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/optiga_comms/ifx_i2c/ifx_i2c_config.c68
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/optiga_comms/ifx_i2c/ifx_i2c_data_link_layer.c568
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/optiga_comms/ifx_i2c/ifx_i2c_physical_layer.c742
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/optiga_comms/ifx_i2c/ifx_i2c_transport_layer.c502
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/optiga_comms/optiga_comms_ifx_i2c.c250
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/pal/nrf5x/pal_gpio.c97
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/pal/nrf5x/pal_i2c.c314
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/pal/nrf5x/pal_ifx_i2c_config.c71
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/pal/nrf5x/pal_os_event.c127
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/pal/nrf5x/pal_os_timer.c71
25 files changed, 4728 insertions, 0 deletions
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/include/Datatypes.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/include/Datatypes.h
new file mode 100644
index 0000000..2e056fe
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/include/Datatypes.h
@@ -0,0 +1,122 @@
+/**
+* \copyright
+* Copyright (c) 2018, Infineon Technologies AG
+* All rights reserved.
+*
+* This software is provided with terms and conditions as specified in OPTIGA(TM) Trust X Evaluation Kit License Agreement.
+* \endcopyright
+*
+* \author Infineon AG
+*
+* \file
+*
+* \brief This file contains the type definitions for the fundamental data types.
+*
+*
+*
+*/
+
+#ifndef _DATATYPES_H_
+#define _DATATYPES_H_
+
+/******************************************************************************
+* required includes
+* Setup common include order for the used types and definitions
+******************************************************************************/
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+
+/******************************************************************************
+* DataTypes.h
+******************************************************************************/
+
+/******************************************************************************
+* defines
+******************************************************************************/
+
+/// @cond hidden
+#ifndef _OPTIGA_EXPORTS_DLLEXPORT_H_
+#define _OPTIGA_EXPORTS_DLLEXPORT_H_
+
+#if defined(WIN32) || defined(_WIN32)
+
+#ifdef OPTIGA_LIB_EXPORTS
+#define LIBRARY_EXPORTS __declspec(dllexport)
+#elif defined(OPTIGA_LIB_EXCLUDE_IMPORT)
+#define LIBRARY_EXPORTS
+#else
+#define LIBRARY_EXPORTS __declspec(dllimport)
+#endif // OPTIGA_LIB_EXPORTS
+
+#else
+#define LIBRARY_EXPORTS
+#endif //WIN32
+
+#endif /*_OPTIGA_EXPORTS_DLLEXPORT_H_*/
+/// @endcond
+
+/// Definition for false
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+/// Definition for true
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+/******************************************************************************
+* fundamental typedefs
+******************************************************************************/
+
+/// Typedef for one byte integer
+typedef char char_t;
+
+/// Typedef for native byte pointer
+typedef uint8_t* puint8_t;
+
+/// Typedef for a 4 byte unsigned integer pointer
+typedef uint32_t* puint32_t;
+
+/// Typedef for unsigned word pointer
+typedef uint16_t* puint16_t ;
+
+/// Typedef for a void
+typedef void Void;
+
+/// Typedef for a double word
+typedef double double_t;
+
+/// Typedef for a float
+typedef float float_t;
+
+/// Typedef for a boolean
+typedef uint8_t bool_t;
+
+/// Typedef for Handle
+typedef Void* hdl_t;
+
+/// typedef for host library status
+typedef uint16_t host_lib_status_t;
+
+/**
+ * \brief Structure to specify a byte stream consisting of length and data
+ * pointer.
+ */
+typedef struct sbBlob_d
+{
+ /// Length of the byte stream
+ uint16_t wLen;
+
+ /// Pointer to byte array which contains the data stream
+ uint8_t *prgbStream;
+} sbBlob_d;
+
+/// typedef for application event handler
+typedef void (*app_event_handler_t)(void* upper_layer_ctx, host_lib_status_t event);
+
+#ifndef _STATIC_H
+#define _STATIC_H static
+#endif
+#endif /* __DATATYPES_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/include/ifx_i2c.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/include/ifx_i2c.h
new file mode 100644
index 0000000..0a3b586
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/include/ifx_i2c.h
@@ -0,0 +1,90 @@
+/**
+* \copyright
+* Copyright (c) 2018, Infineon Technologies AG
+* All rights reserved.
+*
+* This software is provided with terms and conditions as specified in OPTIGA(TM) Trust X Evaluation Kit License Agreement.
+* \endcopyright
+*
+* \author Infineon AG
+*
+* \file ifx_i2c.h
+*
+* \brief This file defines the API prototype for IFX I2C protocol v1.65 wrapper.
+*
+* \addtogroup grIFXI2C
+* @{
+*/
+
+#ifndef _IFXI2C_H_
+#define _IFXI2C_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***********************************************************************************************************************
+ * HEADER FILES
+ **********************************************************************************************************************/
+#include "Datatypes.h"
+#include "ifx_i2c_config.h"
+/***********************************************************************************************************************
+* MACROS
+***********************************************************************************************************************/
+
+/***********************************************************************************************************************
+
+* ENUMS
+***********************************************************************************************************************/
+
+/** @brief IFX I2C Reset types */
+typedef enum ifx_i2c_reset_type
+{
+ /// Cold reset. Both reset pin and vdd pin are toggled low and then high
+ IFX_I2C_COLD_RESET = 0U,
+ /// Soft reset. 0x0000 is written to IFX-I2C Soft reset register
+ IFX_I2C_SOFT_RESET = 1U,
+ /// Warm reset. Only reset pin is toggled low and then high
+ IFX_I2C_WARM_RESET = 2U
+} ifx_i2c_reset_type_t;
+/***********************************************************************************************************************
+* DATA STRUCTURES
+***********************************************************************************************************************/
+/***********************************************************************************************************************
+* API PROTOTYPES
+**********************************************************************************************************************/
+
+/**
+ * \brief Initializes the IFX I2C protocol stack for a given context.
+ */
+host_lib_status_t ifx_i2c_open(ifx_i2c_context_t *p_ctx);
+
+/**
+ * \brief Resets the I2C slave.
+ */
+host_lib_status_t ifx_i2c_reset(ifx_i2c_context_t *p_ctx, ifx_i2c_reset_type_t reset_type);
+
+/**
+ * \brief Sends a command and receives a response for the command.
+ */
+host_lib_status_t ifx_i2c_transceive(ifx_i2c_context_t *p_ctx,const uint8_t* p_data, const uint16_t* p_data_length,
+ uint8_t* p_buffer, uint16_t* p_buffer_len);
+
+/**
+ * \brief Closes the IFX I2C protocol stack for a given context.
+ */
+host_lib_status_t ifx_i2c_close(ifx_i2c_context_t *p_ctx);
+
+/**
+ * \brief Sets the slave address of the target device.
+ */
+host_lib_status_t ifx_i2c_set_slave_address(ifx_i2c_context_t *p_ctx, uint8_t slave_address, uint8_t persistent);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* _IFXI2C_H_ */
+/**
+ * @}
+ **/
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/include/ifx_i2c_config.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/include/ifx_i2c_config.h
new file mode 100644
index 0000000..bf1fa2f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/include/ifx_i2c_config.h
@@ -0,0 +1,296 @@
+/**
+* \copyright
+* Copyright (c) 2018, Infineon Technologies AG
+* All rights reserved.
+*
+* This software is provided with terms and conditions as specified in OPTIGA(TM) Trust X Evaluation Kit License Agreement.
+* \endcopyright
+*
+* \author Infineon AG
+*
+* \file ifx_i2c_config.h
+*
+* \brief This file defines the structures and macros for the Infineon I2C Protocol.
+*
+* \addtogroup grIFXI2C
+* @{
+*/
+
+#ifndef _IFX_I2C_CONFIG_H_
+#define _IFX_I2C_CONFIG_H_
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***********************************************************************************************************************
+* HEADER FILES
+**********************************************************************************************************************/
+// Protocol Stack Includes
+#include <stdint.h>
+#include "pal_i2c.h"
+#include "pal_gpio.h"
+#include "pal_os_timer.h"
+
+/***********************************************************************************************************************
+* MACROS
+**********************************************************************************************************************/
+
+/** @brief I2C slave address of the Infineon device */
+#define IFX_I2C_BASE_ADDR (0x30)
+
+/** @brief Physical Layer: polling interval in microseconds */
+#define PL_POLLING_INVERVAL_US (1000)
+/** @brief Physical layer: maximal attempts */
+#define PL_POLLING_MAX_CNT (200)
+/** @brief Physical Layer: data register polling interval in microseconds */
+#define PL_DATA_POLLING_INVERVAL_US (5000)
+/** @brief Physical Layer: guard time interval in microseconds */
+#define PL_GUARD_TIME_INTERVAL_US (50)
+
+/** @brief Data link layer: maximum frame size */
+#define DL_MAX_FRAME_SIZE (300)
+/** @brief Data link layer: header size */
+#define DL_HEADER_SIZE (5)
+/** @brief Data link layer: maximum number of retries in case of transmission error */
+#define DL_TRANS_REPEAT (3)
+/** @brief Data link layer: Trans timeout in milliseconds*/
+#define PL_TRANS_TIMEOUT_MS (10)
+
+/** @brief Transport layer: Maximum exit timeout in seconds */
+#define TL_MAX_EXIT_TIMEOUT (6)
+
+/** @brief Reset low time for GPIO pin toggling */
+#define RESET_LOW_TIME_MSEC (2000)
+/** @brief Start up time */
+#define STARTUP_TIME_MSEC (12000)
+
+/** @brief Protocol Stack: Status codes for success */
+#define IFX_I2C_STACK_SUCCESS (0x00)
+/** @brief Protocol Stack: Status codes for error */
+#define IFX_I2C_STACK_ERROR (0x01)
+/** @brief Protocol Stack: Status codes busy */
+#define IFX_I2C_STACK_BUSY (0x02)
+/** @brief Protocol Stack: Memory insufficient */
+#define IFX_I2C_STACK_MEM_ERROR (0x03)
+/** @brief Protocol Stack: Fatal error. Used internal to IFX I2C Stack */
+#define IFX_I2C_FATAL_ERROR (0x04)
+
+/** @brief Offset of Datalink header in tx_frame_buffer */
+#define IFX_I2C_DL_HEADER_OFFSET (0)
+/** @brief Offset of Transport header in tx_frame_buffer */
+#define IFX_I2C_TL_HEADER_OFFSET (IFX_I2C_DL_HEADER_OFFSET+3)
+
+/** @brief Protocol Stack debug switch for physical layer (set to 0 or 1) */
+#define IFX_I2C_LOG_PL 0
+/** @brief Protocol Stack debug switch for data link layer (set to 0 or 1) */
+#define IFX_I2C_LOG_DL 0
+/** @brief Protocol Stack debug switch for transport layer (set to 0 or 1) */
+#define IFX_I2C_LOG_TL 0
+
+/** @brief Log ID number for physical layer */
+#define IFX_I2C_LOG_ID_PL 0x00
+/** @brief Log ID number for data link layer */
+#define IFX_I2C_LOG_ID_DL 0x01
+/** @brief Log ID number for transport layer */
+#define IFX_I2C_LOG_ID_TL 0x02
+/** @brief Log ID number for platform abstraction layer */
+#define IFX_I2C_LOG_ID_PAL 0x04
+
+/***********************************************************************************************************************
+* ENUMS
+***********************************************************************************************************************/
+
+
+/***********************************************************************************************************************
+* DATA STRUCTURES
+***********************************************************************************************************************/
+typedef struct ifx_i2c_context ifx_i2c_context_t;
+
+/** @brief Event handler function prototype */
+typedef void (*ifx_i2c_event_handler_t)(struct ifx_i2c_context* ctx, host_lib_status_t event, const uint8_t* data, uint16_t data_len);
+
+/** @brief Physical layer structure */
+typedef struct ifx_i2c_pl
+{
+ // Physical Layer low level interface variables
+
+ /// Physical layer buffer
+ uint8_t buffer[DL_MAX_FRAME_SIZE+1];
+ /// Tx length
+ uint16_t buffer_tx_len;
+ /// Rx length
+ uint16_t buffer_rx_len;
+ /// Action on register, read/write
+ uint8_t register_action;
+ /// i2c read/i2c write
+ uint8_t i2c_cmd;
+ /// Retry counter
+ uint16_t retry_counter;
+
+ // Physical Layer high level interface variables
+
+ /// Action of frame. Tx/Rx
+ uint8_t frame_action;
+ /// Frame state
+ uint8_t frame_state ;
+ /// Pointer to data to be sent
+ uint8_t * p_tx_frame;
+ /// Length of data to be sent
+ uint16_t tx_frame_len;
+ // Upper layer handler
+ ifx_i2c_event_handler_t upper_layer_event_handler;
+
+ // Physical Layer negotiation/soft reset variables
+
+ /// Negotiation state
+ uint8_t negotiate_state;
+ /// Soft reset requested
+ uint8_t request_soft_reset;
+} ifx_i2c_pl_t;
+
+/** @brief Datalink layer structure */
+typedef struct ifx_i2c_dl
+{
+ // Data Link layer internal state variables
+
+ /// Datalink layer state
+ uint8_t state;
+ /// Tx sequence number
+ uint8_t tx_seq_nr;
+ // Rx sequence number
+ uint8_t rx_seq_nr;
+ /// Indicate only Rx required
+ uint8_t action_rx_only;
+ /// Retransmit counter
+ uint8_t retransmit_counter;
+ /// Error occured
+ uint8_t error;
+ /// Resynced
+ uint8_t resynced;
+ /// Timeout value
+ uint32_t data_poll_timeout;
+ /// Transmit buffer size
+ uint16_t tx_buffer_size;
+ /// Receive buffer size
+ uint16_t rx_buffer_size;
+ /// Pointer to main transmit buffers
+ uint8_t* p_tx_frame_buffer;
+ /// Pointer to main receive buffers
+ uint8_t* p_rx_frame_buffer;
+ ///Start time of sending frame
+ uint32_t frame_start_time;
+ // Upper layer Event handler
+ ifx_i2c_event_handler_t upper_layer_event_handler;
+} ifx_i2c_dl_t;
+
+/** @brief Transport layer structure */
+typedef struct ifx_i2c_tl
+{
+ // Transport Layer state and buffer
+
+ /// Transport layer state
+ uint8_t state;
+ /// Pointer to packet provided by user
+ uint8_t* p_actual_packet;
+ /// Total received data
+ uint16_t total_recv_length;
+ /// Actual length of user provided packet
+ uint16_t actual_packet_length;
+ /// Offset till which data is sent from p_actual_packet
+ uint16_t packet_offset;
+ /// Maximum length of packet at transport layer
+ uint16_t max_packet_length;
+ /// Pointer to user provided receive buffer
+ uint8_t* p_recv_packet_buffer;
+ /// Length of receive buffer
+ uint16_t* p_recv_packet_buffer_length;
+ /// Start time of the transport layer API
+ uint32_t api_start_time;
+ ///Chaining error coutn from slave
+ uint8_t chaining_error_count;
+ ///Chaining error count for master
+ uint8_t master_chaining_error_count;
+ ///State to check last chaining state
+ uint8_t previous_chaining;
+ /// transmission done
+ uint8_t transmission_completed;
+ /// Error event state
+ uint8_t error_event;
+
+ /// Upper layer event handler
+ ifx_i2c_event_handler_t upper_layer_event_handler;
+} ifx_i2c_tl_t;
+
+/** @brief IFX I2C context structure */
+struct ifx_i2c_context
+{
+ /// I2C Slave address
+ uint8_t slave_address;
+ /// Frequency of i2c master
+ uint16_t frequency;
+ /// Data link layer frame size
+ uint16_t frame_size;
+ /// Pointer to pal gpio context for vdd
+ pal_gpio_t* p_slave_vdd_pin;
+ /// Pointer to pal gpio context for reset
+ pal_gpio_t* p_slave_reset_pin;
+ /// Pointer to pal i2c context
+ pal_i2c_t* p_pal_i2c_ctx;
+
+ /// Upper layer event handler
+ app_event_handler_t upper_layer_event_handler;
+ /// Upper layer context
+ void* p_upper_layer_ctx;
+ /// Pointer to upper layer rx buffer
+ uint8_t* p_upper_layer_rx_buffer;
+ /// Pointer to length of upper layer rx buffer
+ uint16_t* p_upper_layer_rx_buffer_len;
+
+ /// Protocol variables
+ /// ifx i2c wrapper apis state
+ uint8_t state;
+ /// ifx i2c wrapper api status
+ uint8_t status;
+ /// reset states
+ uint8_t reset_state;
+ /// type of reset
+ uint8_t reset_type;
+ /// init pal
+ uint8_t do_pal_init;
+
+ /// Transport layer context
+ ifx_i2c_tl_t tl;
+ /// Datalink layer context
+ ifx_i2c_dl_t dl;
+ /// Physical layer context
+ ifx_i2c_pl_t pl;
+
+ /// IFX I2C tx frame of max length
+ uint8_t tx_frame_buffer[DL_MAX_FRAME_SIZE];
+ /// IFX I2C rx frame of max length
+ uint8_t rx_frame_buffer[DL_MAX_FRAME_SIZE];
+
+};
+
+/***********************************************************************************************************************
+* GLOBAL
+***********************************************************************************************************************/
+
+/** @brief IFX I2C Instance */
+extern ifx_i2c_context_t ifx_i2c_context_0;
+
+/***********************************************************************************************************************
+* LOCAL ROUTINES
+***********************************************************************************************************************/
+
+/***********************************************************************************************************************
+* API PROTOTYPES
+**********************************************************************************************************************/
+
+/**
+ * @}
+ **/
+#ifdef __cplusplus
+}
+#endif
+#endif /* _IFX_I2C_CONFIG_H_ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/include/ifx_i2c_data_link_layer.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/include/ifx_i2c_data_link_layer.h
new file mode 100644
index 0000000..ae89ff3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/include/ifx_i2c_data_link_layer.h
@@ -0,0 +1,103 @@
+/**
+* \copyright
+* Copyright (c) 2018, Infineon Technologies AG
+* All rights reserved.
+*
+* This software is provided with terms and conditions as specified in OPTIGA(TM) Trust X Evaluation Kit License Agreement.
+* \endcopyright
+*
+* \author Infineon AG
+*
+* \file ifx_i2c_data_link_layer.h
+*
+* \brief This file defines the API prototype for data link layer of the Infineon I2C Protocol Stack library.
+*
+* \addtogroup grIFXI2C
+* @{
+*/
+
+#ifndef _IFX_I2C_DATA_LINK_LAYER_H_
+#define _IFX_I2C_DATA_LINK_LAYER_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***********************************************************************************************************************
+* HEADER FILES
+**********************************************************************************************************************/
+#include "ifx_i2c_config.h"
+
+/***********************************************************************************************************************
+* MACROS
+**********************************************************************************************************************/
+/** @brief Error event propagated to upper layer */
+#define IFX_I2C_DL_EVENT_ERROR (0x01)
+/** @brief Transmit success event propagated to upper layer (bit field 1) */
+#define IFX_I2C_DL_EVENT_TX_SUCCESS (0x02)
+/** @brief Receive success event propagated to upper layer (bit field 3)*/
+#define IFX_I2C_DL_EVENT_RX_SUCCESS (0x04)
+
+/***********************************************************************************************************************
+* ENUMS
+**********************************************************************************************************************/
+/***********************************************************************************************************************
+* DATA STRUCTURES
+***********************************************************************************************************************/
+/***********************************************************************************************************************
+* API PROTOTYPES
+**********************************************************************************************************************/
+/**
+ * @brief Function for initializing the module.
+ *
+ * Function initializes and enables the module and registers
+ * an event handler to receive events from this module.
+ * @attention This function must be called before using the module.
+ *
+ * @param[in,out] p_ctx Pointer to ifx i2c context.
+ * @param[in] handler Function pointer to the event handler of the upper layer.
+ *
+ * @retval IFX_I2C_STACK_SUCCESS If initialization was successful.
+ * @retval IFX_I2C_STACK_ERROR If the module is already initialized.
+ */
+host_lib_status_t ifx_i2c_dl_init(ifx_i2c_context_t *p_ctx,ifx_i2c_event_handler_t handler);
+
+/**
+ * @brief Function for sending a frame.
+ *
+ * Asynchronous function to send a frame. The function returns immediately.
+ * One of the following events is propagated to the event handler registered
+ * with @ref ifx_i2c_dl_init.
+ *
+ * @param[in,out] p_ctx Pointer to ifx i2c context.
+ * @param[in] frame_len Frame length.
+ *
+ * @retval IFX_I2C_STACK_SUCCESS If function was successful.
+ * @retval IFX_I2C_STACK_ERROR If the module is busy.
+ */
+host_lib_status_t ifx_i2c_dl_send_frame(ifx_i2c_context_t *p_ctx,uint16_t frame_len);
+
+/**
+ * @brief Function for receiving a frame.
+ *
+ * Asynchronous function to receive a frame. The function returns immediately.
+ * One of the following events is propagated to the event handler registered
+ * with @ref ifx_i2c_dl_init.
+ *
+ * @param[in,out] p_ctx Pointer to ifx i2c context.
+ *
+ * @retval IFX_I2C_STACK_SUCCESS If function was successful.
+ * @retval IFX_I2C_STACK_ERROR If the module is busy.
+ */
+host_lib_status_t ifx_i2c_dl_receive_frame(ifx_i2c_context_t *p_ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _IFX_I2C_DATA_LINK_LAYER_H_ */
+
+
+/**
+ * @}
+ **/
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/include/ifx_i2c_physical_layer.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/include/ifx_i2c_physical_layer.h
new file mode 100644
index 0000000..18366f7
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/include/ifx_i2c_physical_layer.h
@@ -0,0 +1,110 @@
+/**
+* \copyright
+* Copyright (c) 2018, Infineon Technologies AG
+* All rights reserved.
+*
+* This software is provided with terms and conditions as specified in OPTIGA(TM) Trust X Evaluation Kit License Agreement.
+* \endcopyright
+*
+* \author Infineon AG
+*
+* \file ifx_i2c_physical_layer.h
+*
+* \brief This file defines the API prototype for physical layer of the Infineon I2C Protocol Stack library.
+*
+* \addtogroup grIFXI2C
+* @{
+*/
+
+#ifndef _IFX_I2C_PHYSICAL_LAYER_H_
+#define _IFX_I2C_PHYSICAL_LAYER_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***********************************************************************************************************************
+* HEADER FILES
+**********************************************************************************************************************/
+#include "ifx_i2c_config.h"
+
+/***********************************************************************************************************************
+* MACROS
+**********************************************************************************************************************/
+/***********************************************************************************************************************
+* ENUMS
+**********************************************************************************************************************/
+/***********************************************************************************************************************
+* DATA STRUCTURES
+***********************************************************************************************************************/
+/***********************************************************************************************************************
+* API PROTOTYPES
+**********************************************************************************************************************/
+/**
+ * @brief Function for initializing the module.
+ *
+ * Function initializes and enables the module and registers
+ * an event handler to receive events from this module.
+ * @attention This function must be called before using the module.
+ *
+ * @param[in,out] p_ctx Pointer to ifx i2c context.
+ * @param[in] handler Function pointer to the event handler of the upper layer.
+ *
+ * @retval IFX_I2C_STACK_SUCCESS If initialization was successful.
+ * @retval IFX_I2C_STACK_ERROR If the module is already initialized.
+ */
+host_lib_status_t ifx_i2c_pl_init(ifx_i2c_context_t *p_ctx,ifx_i2c_event_handler_t handler);
+
+/**
+ * @brief Function for sending a frame.
+ *
+ * Asynchronous function to send a frame. The function returns immediately.
+ * One of the following events is propagated to the event handler registered
+ * with @ref ifx_i2c_pl_init
+ *
+ * @param[in,out] p_ctx Pointer to ifx i2c context.
+ * @param[in] p_frame Buffer containing the frame.
+ * @param[in] frame_len Frame length.
+ *
+ * @retval IFX_I2C_STACK_SUCCESS If function was successful.
+ * @retval IFX_I2C_STACK_ERROR If the module is busy.
+ */
+host_lib_status_t ifx_i2c_pl_send_frame(ifx_i2c_context_t *p_ctx,uint8_t* p_frame, uint16_t frame_len);
+
+/**
+ * @brief Function for receiving a frame.
+ *
+ * Asynchronous function to receive a frame. The function returns immediately.
+ * One of the following events is propagated to the event handler registered
+ * with @ref ifx_i2c_pl_init
+ *
+ * @param[in] p_ctx Pointer to ifx i2c context.
+ *
+ * @retval IFX_I2C_STACK_SUCCESS If function was successful.
+ * @retval IFX_I2C_STACK_ERROR If the module is busy.
+ */
+host_lib_status_t ifx_i2c_pl_receive_frame(ifx_i2c_context_t *p_ctx);
+
+
+/**
+ * @brief Function for setting slave address.
+ *
+ * Synchronous function to set slave address.
+ *
+ * @param[in] p_ctx Pointer to ifx i2c context.
+ * @param[in] slave_address Holds new slave address[7 Bit] to be set.
+ * @param[in] storage_type 0 - To set the Slave address until next reset.<br>
+ * Non-zero - To set the slave address to persistent memory.
+ *
+ * @retval IFX_I2C_STACK_SUCCESS If function was successful.
+ * @retval IFX_I2C_STACK_ERROR If setting slave address fails.
+ */
+host_lib_status_t ifx_i2c_pl_write_slave_address(ifx_i2c_context_t *p_ctx, uint8_t slave_address, uint8_t storage_type);
+/**
+ * @}
+ **/
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* _IFX_I2C_PHYSICAL_LAYER_H_ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/include/ifx_i2c_transport_layer.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/include/ifx_i2c_transport_layer.h
new file mode 100644
index 0000000..6b61011
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/include/ifx_i2c_transport_layer.h
@@ -0,0 +1,84 @@
+/**
+* \copyright
+* Copyright (c) 2018, Infineon Technologies AG
+* All rights reserved.
+*
+* This software is provided with terms and conditions as specified in OPTIGA(TM) Trust X Evaluation Kit License Agreement.
+* \endcopyright
+*
+* \author Infineon AG
+*
+* \file ifx_i2c_transport_layer.h
+*
+* \brief This file defines the API prototype for transport layer of the Infineon I2C Protocol Stack library.
+*
+* \addtogroup grIFXI2C
+* @{
+*/
+
+#ifndef _IFX_I2C_TRANSPORT_LAYER_H_
+#define _IFX_I2C_TRANSPORT_LAYER_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***********************************************************************************************************************
+* HEADER FILES
+**********************************************************************************************************************/
+#include "ifx_i2c_config.h"
+#include "pal_os_timer.h"
+
+/***********************************************************************************************************************
+* MACROS
+**********************************************************************************************************************/
+/***********************************************************************************************************************
+* ENUMS
+**********************************************************************************************************************/
+/***********************************************************************************************************************
+* DATA STRUCTURES
+***********************************************************************************************************************/
+/***********************************************************************************************************************
+* API PROTOTYPES
+**********************************************************************************************************************/
+/**
+ * @brief Function for initializing the module.
+ *
+ * Function initializes and enables the module and registers
+ * an event handler to receive events from this module.
+ * @attention This function must be called before using the module.
+ *
+ * @param[in,out] p_ctx Pointer to ifx i2c context.
+ * @param[in] handler Function pointer to the event handler of the upper layer.
+ *
+ * @retval IFX_I2C_STACK_SUCCESS If initialization was successful.
+ * @retval IFX_I2C_STACK_ERROR If the module is already initialized.
+ */
+host_lib_status_t ifx_i2c_tl_init(ifx_i2c_context_t *p_ctx,ifx_i2c_event_handler_t handler);
+
+/**
+ * @brief Function to transmit and receive a packet.
+ *
+ * Asynchronous function to send and receive a packet.
+ * The function returns immediately. One of the following events is
+ * propagated to the event handler registered with @ref ifx_i2c_tl_init
+ *
+ * @param[in,out] p_ctx Pointer to ifx i2c context.
+ * @param[in] p_packet Buffer containing the packet header.
+ * @param[in] packet_len Packet header length.
+ * @param[in] p_recv_packet Buffer containing the packet payload.
+ * @param[in] recv_packet_len Packet payload length.
+ *
+ * @retval IFX_I2C_STACK_SUCCESS If function was successful.
+ * @retval IFX_I2C_STACK_ERROR If the module is busy.
+ */
+host_lib_status_t ifx_i2c_tl_transceive(ifx_i2c_context_t *p_ctx,uint8_t* p_packet, uint16_t packet_len,
+ uint8_t* p_recv_packet, uint16_t* recv_packet_len);
+
+/**
+ * @}
+ **/
+#ifdef __cplusplus
+}
+#endif
+#endif /* IFX_I2C_TRANSPORT_LAYER_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/include/optiga_comms.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/include/optiga_comms.h
new file mode 100644
index 0000000..d04cd95
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/include/optiga_comms.h
@@ -0,0 +1,90 @@
+/**
+* \copyright
+* Copyright (c) 2018, Infineon Technologies AG
+* All rights reserved.
+*
+* This software is provided with terms and conditions as specified in OPTIGA(TM) Trust X Evaluation Kit License Agreement.
+* \endcopyright
+*
+* \author Infineon AG
+*
+* \file
+*
+* \brief This file implements optiga comms abstraction layer for IFX I2C Protocol.
+*
+* \addtogroup grOptigaComms
+* @{
+*/
+
+#ifndef _OPTIGA_COMMS_H_
+#define _OPTIGA_COMMS_H_
+/**********************************************************************************************************************
+ * HEADER FILES
+ *********************************************************************************************************************/
+#include "Datatypes.h"
+
+/**********************************************************************************************************************
+ * MACROS
+ *********************************************************************************************************************/
+
+/// Succesfull execution
+#define OPTIGA_COMMS_SUCCESS 0x0000
+/// Error in execution
+#define OPTIGA_COMMS_ERROR 0x0001
+/// Busy, doing operation
+#define OPTIGA_COMMS_BUSY 0x0002
+
+/**********************************************************************************************************************
+ * DATA STRUCTURES
+ *********************************************************************************************************************/
+
+/** @brief optiga comms structure */
+typedef struct optiga_comms
+{
+ /// Comms structure pointer
+ void* comms_ctx;
+ /// Upper layer contect
+ void* upper_layer_ctx;
+ /// Upper layer handler
+ app_event_handler_t upper_layer_handler;
+ /// Optiga comms state
+ uint8_t state;
+}optiga_comms_t;
+
+extern optiga_comms_t optiga_comms;
+
+/**********************************************************************************************************************
+ * API Prototypes
+ *********************************************************************************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Opens the communication channel with OPTIGA.
+ */
+LIBRARY_EXPORTS host_lib_status_t optiga_comms_open(optiga_comms_t *p_ctx);
+
+/**
+ * \brief Resets the OPTIGA.
+ */
+LIBRARY_EXPORTS host_lib_status_t optiga_comms_reset(optiga_comms_t *p_ctx,uint8_t reset_type);
+
+/**
+ * \brief Sends and receives the APDU.
+ */
+LIBRARY_EXPORTS host_lib_status_t optiga_comms_transceive(optiga_comms_t *p_ctx,const uint8_t* p_data,
+ const uint16_t* p_data_length,
+ uint8_t* p_buffer, uint16_t* p_buffer_len);
+
+/**
+ * \brief Closes the communication channel with OPTIGA.
+ */
+LIBRARY_EXPORTS host_lib_status_t optiga_comms_close(optiga_comms_t *p_ctx);
+
+/**
+* @}
+*/
+
+#endif /*_OPTIGA_COMMS_H_*/
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/include/pal.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/include/pal.h
new file mode 100644
index 0000000..f66b41a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/include/pal.h
@@ -0,0 +1,60 @@
+/**
+* \copyright
+* Copyright (c) 2018, Infineon Technologies AG
+* All rights reserved.
+*
+* This software is provided with terms and conditions as specified in OPTIGA(TM) Trust X Evaluation Kit License Agreement.
+* \endcopyright
+*
+* \author Infineon AG
+*
+* \file
+*
+* \brief This file implements the prototype declarations of platform abstraction layer
+*
+* \addtogroup grPAL
+* @{
+*/
+
+
+#ifndef _PAL_H_
+#define _PAL_H_
+
+/**********************************************************************************************************************
+ * HEADER FILES
+ *********************************************************************************************************************/
+#include <Datatypes.h>
+
+/**********************************************************************************************************************
+ * pal.h
+ *********************************************************************************************************************/
+
+/**********************************************************************************************************************
+ * MACROS
+ *********************************************************************************************************************/
+
+/// PAL API execution is successful
+#define PAL_STATUS_SUCCESS (0x0000)
+/// PAL API execution failed
+#define PAL_STATUS_FAILURE (0x0001)
+/// PAL I2C is busy
+#define PAL_STATUS_I2C_BUSY (0x0002)
+
+/**********************************************************************************************************************
+ * ENUMS
+ *********************************************************************************************************************/
+/**
+ * \brief PAL return status.
+ */
+typedef uint16_t pal_status_t;
+
+/**********************************************************************************************************************
+ * API Prototypes
+ *********************************************************************************************************************/
+
+#endif /* _PAL_H_ */
+
+/**
+* @}
+*/
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/include/pal_gpio.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/include/pal_gpio.h
new file mode 100644
index 0000000..171811b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/include/pal_gpio.h
@@ -0,0 +1,84 @@
+/**
+* \copyright
+* Copyright (c) 2018, Infineon Technologies AG
+* All rights reserved.
+*
+* This software is provided with terms and conditions as specified in OPTIGA(TM) Trust X Evaluation Kit License Agreement.
+* \endcopyright
+*
+* \author Infineon AG
+*
+* \file
+*
+* \brief This file implements the prototype declarations of pal gpio
+*
+* \addtogroup grPAL
+* @{
+*/
+
+#ifndef _PAL_GPIO_H_
+#define _PAL_GPIO_H_
+
+/**********************************************************************************************************************
+ * HEADER FILES
+ *********************************************************************************************************************/
+
+#include "pal.h"
+
+/**********************************************************************************************************************
+ * MACROS
+ *********************************************************************************************************************/
+
+
+/**********************************************************************************************************************
+ * ENUMS
+ *********************************************************************************************************************/
+
+
+/**********************************************************************************************************************
+ * DATA STRUCTURES
+ *********************************************************************************************************************/
+
+/**
+ * \brief Structure defines the PAL GPIO configuration.
+ */
+typedef struct pal_gpio
+{
+ /// Pointer to gpio platform specific context/structure
+ void* p_gpio_hw;
+
+} pal_gpio_t;
+
+/**********************************************************************************************************************
+ * API Prototypes
+ *********************************************************************************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Initializes the GPIO PAL.
+ */
+void pal_gpio_init(void);
+
+/**
+ * \brief Sets the gpio pin to high state.
+ */
+void pal_gpio_set_high(const pal_gpio_t* p_gpio_context);
+
+/**
+ * \brief Sets the gpio pin to Low state.
+ */
+void pal_gpio_set_low(const pal_gpio_t* p_gpio_context);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _PAL_GPIO_H_ */
+
+/**
+* @}
+*/
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/include/pal_i2c.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/include/pal_i2c.h
new file mode 100644
index 0000000..fd470d3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/include/pal_i2c.h
@@ -0,0 +1,92 @@
+/**
+* \copyright
+* Copyright (c) 2018, Infineon Technologies AG
+* All rights reserved.
+*
+* This software is provided with terms and conditions as specified in OPTIGA(TM) Trust X Evaluation Kit License Agreement.
+* \endcopyright
+*
+* \author Infineon AG
+*
+* \file
+*
+* \brief This file implements the prototype declarations of pal i2c
+*
+* \addtogroup grPAL
+* @{
+*/
+
+#ifndef _PAL_I2C_H_
+#define _PAL_I2C_H_
+
+/**********************************************************************************************************************
+ * HEADER FILES
+ *********************************************************************************************************************/
+
+#include "pal.h"
+
+/**********************************************************************************************************************
+ * MACROS
+ *********************************************************************************************************************/
+/// Event returned when I2C master completes execution
+#define PAL_I2C_EVENT_SUCCESS (0x0000)
+/// Event returned when I2C master operation fails
+#define PAL_I2C_EVENT_ERROR (0x0001)
+/// Event returned when lower level I2C bus is busy
+#define PAL_I2C_EVENT_BUSY (0x0002)
+
+/**********************************************************************************************************************
+ * ENUMS
+ *********************************************************************************************************************/
+
+/**********************************************************************************************************************
+ * DATA STRUCTURES
+ *********************************************************************************************************************/
+/** @brief PAL I2C context structure */
+typedef struct pal_i2c
+{
+ /// Pointer to I2C master platform specific context
+ void* p_i2c_hw_config;
+ /// I2C slave address
+ uint8_t slave_address;
+ /// Pointer to store the callers context information
+ void* upper_layer_ctx;
+ /// Pointer to store the callers handler
+ void* upper_layer_event_handler;
+
+} pal_i2c_t;
+
+/**********************************************************************************************************************
+ * API Prototypes
+ *********************************************************************************************************************/
+/**
+ * @brief Initializes the I2C master.
+ */
+pal_status_t pal_i2c_init(const pal_i2c_t* p_i2c_context);
+
+/**
+ * @brief Sets the I2C Master bitrate
+ */
+pal_status_t pal_i2c_set_bitrate(const pal_i2c_t* p_i2c_context, uint16_t bitrate);
+
+/**
+ * @brief Writes to I2C bus.
+ */
+pal_status_t pal_i2c_write(pal_i2c_t* p_i2c_context, uint8_t* p_data , uint16_t length);
+
+/**
+ * @brief Reads from I2C bus.
+ */
+pal_status_t pal_i2c_read(pal_i2c_t* p_i2c_context, uint8_t* p_data , uint16_t length);
+
+/**
+ * @brief De-initializes the I2C master.
+ */
+pal_status_t pal_i2c_deinit(const pal_i2c_t* p_i2c_context);
+
+#endif /* _PAL_I2C_H_ */
+
+/**
+* @}
+*/
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/include/pal_ifx_i2c_config.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/include/pal_ifx_i2c_config.h
new file mode 100644
index 0000000..0df491a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/include/pal_ifx_i2c_config.h
@@ -0,0 +1,49 @@
+/**
+* \copyright
+* Copyright (c) 2018, Infineon Technologies AG
+* All rights reserved.
+*
+* This software is provided with terms and conditions as specified in OPTIGA(TM) Trust X Evaluation Kit License Agreement.
+* \endcopyright
+*
+* \author Infineon AG
+*
+* \file
+*
+* \brief This file implements the platform abstraction layer extern declarations for ifx i2c.
+*
+* \addtogroup grPAL
+* @{
+*/
+
+#ifndef _PAL_IFX_I2C_CONFIG_H_
+#define _PAL_IFX_I2C_CONFIG_H_
+
+/**********************************************************************************************************************
+ * HEADER FILES
+ *********************************************************************************************************************/
+#include "pal.h"
+#include "pal_i2c.h"
+#include "pal_gpio.h"
+
+/**********************************************************************************************************************
+ * MACROS
+ *********************************************************************************************************************/
+
+
+/**********************************************************************************************************************
+ * ENUMS
+ *********************************************************************************************************************/
+
+/**********************************************************************************************************************
+ * PAL extern definitions for IFX I2C
+ *********************************************************************************************************************/
+extern pal_i2c_t optiga_pal_i2c_context_0;
+extern pal_gpio_t optiga_vdd_0;
+extern pal_gpio_t optiga_reset_0;
+
+#endif /* _PAL_IFX_I2C_CONFIG_H_ */
+
+/**
+* @}
+*/
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/include/pal_os_event.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/include/pal_os_event.h
new file mode 100644
index 0000000..e4a1315
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/include/pal_os_event.h
@@ -0,0 +1,61 @@
+/**
+* \copyright
+* Copyright (c) 2018, Infineon Technologies AG
+* All rights reserved.
+*
+* This software is provided with terms and conditions as specified in OPTIGA(TM) Trust X Evaluation Kit License Agreement.
+* \endcopyright
+*
+* \author Infineon AG
+*
+* \file
+*
+* \brief This file implements the prototype declarations of pal os event
+*
+* \addtogroup grPAL
+* @{
+*/
+
+
+#ifndef _PAL_OS_EVENT_H_
+#define _PAL_OS_EVENT_H_
+
+/**********************************************************************************************************************
+ * HEADER FILES
+ *********************************************************************************************************************/
+
+#include "Datatypes.h"
+
+/**********************************************************************************************************************
+ * MACROS
+ *********************************************************************************************************************/
+
+
+/**********************************************************************************************************************
+ * ENUMS
+ *********************************************************************************************************************/
+
+/**********************************************************************************************************************
+ * PAL extern definitions
+ *********************************************************************************************************************/
+
+/**
+ * @brief typedef for Callback function when timer elapses.
+ */
+typedef void (*register_callback)(void*);
+
+/**
+ * \brief Initializes the OS event PAL.
+ */
+void pal_os_event_init(void);
+
+/**
+ * @brief Callback registration function to trigger once when timer expires.
+ */
+void pal_os_event_register_callback_oneshot(register_callback callback, void* callback_args, uint32_t time_us);
+
+#endif //_PAL_OS_EVENT_H_
+
+/**
+* @}
+*/
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/include/pal_os_timer.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/include/pal_os_timer.h
new file mode 100644
index 0000000..796e39e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/include/pal_os_timer.h
@@ -0,0 +1,76 @@
+/**
+* \copyright
+* Copyright (c) 2018, Infineon Technologies AG
+* All rights reserved.
+*
+* This software is provided with terms and conditions as specified in OPTIGA(TM) Trust X Evaluation Kit License Agreement.
+* \endcopyright
+*
+* \author Infineon AG
+*
+* \file
+*
+* \brief This file implements the prototype declarations of pal os timer functionalities.
+*
+* \addtogroup grPAL
+* @{
+*/
+#ifndef _PAL_OS_TIMER_H_
+#define _PAL_OS_TIMER_H_
+
+/**********************************************************************************************************************
+ * HEADER FILES
+ *********************************************************************************************************************/
+
+#include "pal.h"
+
+/*********************************************************************************************************************
+ * pal_os_timer.h
+*********************************************************************************************************************/
+
+
+/**********************************************************************************************************************
+ * MACROS
+ *********************************************************************************************************************/
+
+
+/**********************************************************************************************************************
+ * ENUMS
+ *********************************************************************************************************************/
+
+
+/**********************************************************************************************************************
+ * DATA STRUCTURES
+ *********************************************************************************************************************/
+
+
+/**********************************************************************************************************************
+ * API Prototypes
+ *********************************************************************************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @brief Gets tick count value in milliseconds
+ */
+uint32_t pal_os_timer_get_time_in_milliseconds(void);
+
+/**
+ * @brief Waits or delay until the supplied milliseconds
+ */
+void pal_os_timer_delay_in_milliseconds(uint16_t milliseconds);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _PAL_OS_TIMER_H_ */
+
+/**
+* @}
+*/
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/include/pal_socket.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/include/pal_socket.h
new file mode 100644
index 0000000..5456bca
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/include/pal_socket.h
@@ -0,0 +1,182 @@
+/**
+* \copyright
+* Copyright© 2018, Infineon Technologies AG
+* All rights reserved.
+*
+* This software is provided with terms and conditions as specified in OPTIGA™ Trust X Evaluation Kit License Agreement.
+* \endcopyright
+*
+* \author Infineon AG
+*
+* \file
+*
+* \brief This file implements the prototype declarations of pal socket functionalities
+* \ingroup grPAL
+* @{
+*/
+
+
+#ifndef _PAL_SOCKET_H_
+#define _PAL_SOCKET_H_
+
+/**********************************************************************************************************************
+ * HEADER FILES
+ *********************************************************************************************************************/
+
+#ifndef WIN32
+ #include "Datatypes.h"
+ #include "DAVE.h"
+ #include "udp.h"
+ #include "inet.h"
+#else
+ #include <winsock2.h>
+ #include "Datatypes.h"
+#endif
+
+#include "ErrorCodes.h"
+#include "UDPErrorCodes.h"
+
+/// @cond hidden
+/**********************************************************************************************************************
+ * MACROS
+ *********************************************************************************************************************/
+#ifndef WIN32
+ #define IPAddressParse(pzIpAddress, psIPAddress) (inet_aton(pzIpAddress, psIPAddress))
+#else
+ #define IPAddressParse(pzIpAddress, psIPAddress) (1)
+#endif
+/// @endcond
+/**********************************************************************************************************************
+ * ENUMS
+ *********************************************************************************************************************/
+
+
+/**********************************************************************************************************************
+ * DATA STRUCTURES
+ *********************************************************************************************************************/
+
+#ifndef WIN32
+/**
+ * \brief Pointer type definition of pal socket receive event callback
+ */
+typedef void (*pal_socket_event_listener)(void *arg, struct udp_pcb *pcb, struct pbuf *p,
+ ip_addr_t *addr, u16_t port);
+#endif
+
+
+
+/**
+ * \brief This structure contains socket communication data
+ */
+typedef enum eRecvMode_d
+{
+ eBlock = 0x10,
+
+ eNonBlock = 0x20
+}eRecvMode_d;
+
+/**
+ * \brief This structure contains socket communication data
+ */
+#ifndef WIN32
+
+typedef struct pal_socket
+{
+
+ ///UDP structure Tx
+ struct udp_pcb *pcbTx;
+
+ ///UDP structure Rx
+ struct udp_pcb *pcbRx;
+
+ //Received IP address
+ ip_addr_t sIPAddress;
+
+ ///Function pointer to hold receive callback
+ pal_socket_event_listener pfListen;
+
+ ///Port for UDP communication
+ uint16_t wPort;
+
+ ///Transport Layer Timeout
+ uint16_t wTimeout;
+
+ ///Enumeration to indicate Blocking or Non blocking
+ uint8_t bMode;
+
+} pal_socket_t;
+
+#else
+
+typedef struct pal_socket
+{
+ ///Received IP address
+ char* sIPAddress;
+
+ ///Port for UDP communication
+ uint16_t wPort;
+
+ ///Pointer to the socket for Receiving
+ SOCKET SocketHdl;
+
+ ///IPv4 Socket address for Receiving
+ SOCKADDR_IN sSocketAddrIn;
+
+ ///Transport Layer Timeout
+ uint16_t wTimeout;
+
+ ///Enumeration to indicate Blocking or Non blocking
+ uint8_t bMode;
+
+} pal_socket_t;
+#endif
+
+/**********************************************************************************************************************
+ * API Prototypes
+ *********************************************************************************************************************/
+
+/**
+ * \brief Assign IP address
+ */
+#ifndef WIN32
+int32_t pal_socket_assign_ip_address(const char* p_ip_address,void *p_input_ip_address);
+#else
+int32_t pal_socket_assign_ip_address(const char_t* p_ip_address,char** p_input_ip_address);
+#endif
+
+/**
+ * \brief Initializes the socket communication structure
+ */
+int32_t pal_socket_init(pal_socket_t* p_socket);
+
+/**
+ * \brief Creates server port and bind
+ */
+int32_t pal_socket_open(pal_socket_t* p_socket,
+ uint16_t port);
+/**
+ * \brief Creates a client port and connect
+ */
+int32_t pal_socket_connect(pal_socket_t* p_socket,
+ uint16_t port);
+/**
+ * \brief Receive data from the client
+ */
+int32_t pal_socket_listen(pal_socket_t* p_socket, uint8_t *p_data,
+ uint32_t *p_length);
+/**
+ * \brief Sends the data to the the client
+ */
+int32_t pal_socket_send(const pal_socket_t* p_socket, uint8_t *p_data,
+ uint32_t length);
+/**
+ * \brief Closes the socket communication and release the udp port
+ */
+void pal_socket_close(pal_socket_t* p_socket);
+
+#endif //_PAL_SOCKET_H_
+
+/**
+* @}
+*/
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/optiga_comms/ifx_i2c/ifx_i2c.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/optiga_comms/ifx_i2c/ifx_i2c.c
new file mode 100644
index 0000000..9c15cfd
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/optiga_comms/ifx_i2c/ifx_i2c.c
@@ -0,0 +1,419 @@
+/**
+* \copyright
+* Copyright (c) 2018, Infineon Technologies AG
+* All rights reserved.
+*
+* This software is provided with terms and conditions as specified in OPTIGA(TM) Trust X Evaluation Kit License Agreement.
+* \endcopyright
+*
+* \author Infineon AG
+*
+* \file ifx_i2c.c
+*
+* \brief This file implements the wrapper API Layer for IFX I2C protocol v1.65.
+*
+* \addtogroup grIFXI2C
+* @{
+*/
+
+/***********************************************************************************************************************
+* HEADER FILES
+**********************************************************************************************************************/
+#include "ifx_i2c.h"
+#include "ifx_i2c_transport_layer.h"
+#include "pal_os_event.h"
+
+/// @cond hidden
+/***********************************************************************************************************************
+* MACROS
+**********************************************************************************************************************/
+
+// IFX I2C states
+#define IFX_I2C_STATE_UNINIT (0x01)
+#define IFX_I2C_STATE_IDLE (0x02)
+#define IFX_I2C_STATUS_BUSY (0x03)
+#define IFX_I2C_STATUS_NOT_BUSY (0x04)
+
+/// IFX I2C Reset states
+#define IFX_I2C_STATE_RESET_PIN_LOW (0xB1)
+#define IFX_I2C_STATE_RESET_PIN_HIGH (0xB2)
+#define IFX_I2C_STATE_RESET_INIT (0xB3)
+
+/***********************************************************************************************************************
+* ENUMS
+**********************************************************************************************************************/
+
+/***********************************************************************************************************************
+* DATA STRUCTURES
+***********************************************************************************************************************/
+
+/***********************************************************************************************************************
+* GLOBAL
+***********************************************************************************************************************/
+
+/***********************************************************************************************************************
+* LOCAL ROUTINES
+***********************************************************************************************************************/
+/// Transport Layer event handler
+void ifx_i2c_tl_event_handler(ifx_i2c_context_t* p_ctx,host_lib_status_t event, const uint8_t* p_data, uint16_t data_len);
+
+/// Performs initialization
+static host_lib_status_t ifx_i2c_init(ifx_i2c_context_t* ifx_i2c_context);
+
+//lint --e{526} suppress "This API is defined in ifx_i2c_physical_layer. Since it is a low level API,
+//to avoid exposing, header file is not included "
+extern host_lib_status_t ifx_i2c_pl_write_slave_address(ifx_i2c_context_t *p_ctx, uint8_t slave_address, uint8_t storage_type);
+/// @endcond
+/***********************************************************************************************************************
+* API PROTOTYPES
+**********************************************************************************************************************/
+/**
+ * Initializes the IFX I2C protocol stack for the given context.
+ * <br>
+ * <br>
+ * \image html ifx_i2c_open.png "ifx_i2c_open()" width=20cm
+ *
+ *<b>Pre Conditions:</b>
+ * - None<br>
+ *
+ *<b>API Details:</b>
+ * - Performs a reset sequence.<br>
+ * - Initializes the I2C slave device.<br>
+ * - Initializes the ifx i2c protocol stack and registers the event callbacks.
+ * - Negotiates the frame size and bit rate with the I2C slave.<br>
+ *<br>
+ *
+ *<b>User Input:</b><br>
+ * - The input #ifx_i2c_context_t p_ctx must not be NULL.
+ * - The following parameters in #ifx_i2c_context_t must be initialized with appropriate values <br>
+ * - <b>slave address</b> : Address of I2C slave
+ * - <b>frame_size</b> : Frame size in bytes.Minimum supported value is 16 bytes.<br>
+ * - It is recommended not to use a value greater than the slave's frame size.
+ * - The user specified frame size is written to I2C slave's frame size register.
+ * The frame size register is read back from I2C slave.
+ * This frame value is used by the ifx-i2c protocol even if it is not equal to the user specified value.
+ *
+ * - <b>frequency</b> : Frequency/speed of I2C master in KHz.
+ * - This must be lowest of the maximum frequency supported by the devices (master/slave) connected on the bus.
+ * - Initial negotiation starts with a frequency of 100KHz.
+ * - If the user specified frequency is more than 400 KHz, the I2C slave is configured to operate in "Fm+" mode,
+ * otherwise the I2C slave is configured for "SM & Fm" mode. <br>
+ * - If the user specified frequency frequency negotiation fails, the I2C master frequency remains at 100KHz<br>
+ *
+ * - <b>upper_layer_event_handler</b> : Upper layer event handler.This is invoked when #ifx_i2c_open() is asynchronously completed.
+ * - <b>upper_layer_ctx</b> : Context of upper layer.
+ * - <b>p_slave_vdd_pin</b> : GPIO pin for VDD. If not set, cold reset is not done.
+ * - <b>p_slave_reset_pin</b> : GPIO pin for Reset. If not set, warm reset is not done.
+ *
+ *<b>Notes:</b>
+ * - The values of registers MAX_SCL_FREQU and DATA_REG_LEN, read from slave are not validated.
+ * - At present, only single instance of #ifx_i2c_context_t is supported.
+ *
+ *<br>
+ *
+ * \param[in,out] p_ctx Pointer to #ifx_i2c_context_t
+ *
+ * \retval #IFX_I2C_STACK_SUCCESS
+ * \retval #IFX_I2C_STACK_ERROR
+ */
+host_lib_status_t ifx_i2c_open(ifx_i2c_context_t *p_ctx)
+{
+ host_lib_status_t api_status = (int32_t)IFX_I2C_STACK_ERROR;
+
+ //If api status is not busy, proceed
+ if ((IFX_I2C_STATUS_BUSY != p_ctx->status))
+ {
+ p_ctx->p_pal_i2c_ctx->upper_layer_ctx = p_ctx;
+ p_ctx->reset_type = (uint8_t)IFX_I2C_COLD_RESET;
+ p_ctx->reset_state = IFX_I2C_STATE_RESET_PIN_LOW;
+ p_ctx->do_pal_init = TRUE;
+ p_ctx->state = IFX_I2C_STATE_UNINIT;
+
+ // Init GPIO and OS event PAL
+ pal_gpio_init();
+ pal_os_event_init();
+
+ api_status = ifx_i2c_init(p_ctx);
+ if(IFX_I2C_STACK_SUCCESS == api_status)
+ {
+ p_ctx->status = IFX_I2C_STATUS_BUSY;
+ }
+ }
+
+ return api_status;
+}
+
+/**
+ * Resets the I2C slave and initializes the IFX I2C protocol stack for the given context.
+ * <br>
+ * <br>
+ * \image html ifx_i2c_reset.png "ifx_i2c_reset()" width=20cm
+ *
+ *<b>Pre Conditions:</b>
+ * - IFX I2C protocol stack must be initialized.<br>
+ *
+ *<b>API Details:</b>
+ * - Resets the I2C slave.<br>
+ * - Initializes the ifx i2c protocol stack.<br>
+ * - Re-Initializes and negotiates the frame size and bit rate with the I2C slave.
+ * The values remain same as that in previous #ifx_i2c_open().<br>
+ *<br>
+ *
+ *<b>User Input:</b><br>
+ * - The input #ifx_i2c_context_t p_ctx must not be NULL.
+ *
+ *<b>Notes:</b>
+ * For COLD and WARM reset type: If the gpio(vdd and/or reset) pins are not configured,
+ * the API continues without any failure return status<br>
+ *
+ * \param[in,out] p_ctx Pointer to #ifx_i2c_context_t
+ * \param[in,out] reset_type type of reset
+ *
+ * \retval #IFX_I2C_STACK_SUCCESS
+ * \retval #IFX_I2C_STACK_ERROR
+ */
+host_lib_status_t ifx_i2c_reset(ifx_i2c_context_t *p_ctx, ifx_i2c_reset_type_t reset_type)
+{
+ host_lib_status_t api_status = (int32_t)IFX_I2C_STACK_ERROR;
+
+ // Proceed, if not busy and in idle state
+ if ((IFX_I2C_STATE_IDLE == p_ctx->state) && (IFX_I2C_STATUS_BUSY != p_ctx->status))
+ {
+ p_ctx->reset_type = (uint8_t)reset_type;
+ p_ctx->reset_state = IFX_I2C_STATE_RESET_PIN_LOW;
+ p_ctx->do_pal_init = FALSE;
+
+ api_status = ifx_i2c_init(p_ctx);
+ if(IFX_I2C_STACK_SUCCESS == api_status)
+ {
+ p_ctx->status = IFX_I2C_STATUS_BUSY;
+ }
+ }
+ return api_status;
+}
+
+/**
+
+ * Sends a command and receives a response for the command.<br>
+ * <br>
+ * \image html ifx_i2c_transceive.png "ifx_i2c_transceive()" width=20cm
+ *
+ *
+ *<b>Pre Conditions:</b>
+ * - IFX I2C protocol stack must be initialized.<br>
+ *
+ *<b>API Details:</b>
+ * - Transmit data(Command) to I2C slave.<br>
+ * - Receive data(Response) from I2C slave.<br>
+ *<br>
+ *
+ *<b>User Input:</b><br>
+ * - The input #ifx_i2c_context_t p_ctx must not be NULL.
+ * - The following parameters in #ifx_i2c_context_t must be initialized with appropriate values <br>
+ * - <b>upper_layer_event_handler</b> : Upper layer event handler, if it is different from that in #ifx_i2c_open().
+ * This is invoked when #ifx_i2c_transceive is asynchronously completed.
+ * - <b>upper_layer_ctx</b> : Context of upper layer, if it is different from that in #ifx_i2c_open.
+ *
+ *<b>Notes:</b>
+ * - The actual number of bytes received is stored in p_rx_buffer_len. In case of error,p_rx_buffer_len is set to 0.<br>
+ * - If the size of p_rx_buffer is zero or insufficient to copy the response bytes then
+ * #IFX_I2C_STACK_MEM_ERROR error is returned.
+ *
+ * \param[in,out] p_ctx Pointer to #ifx_i2c_context_t
+ * \param[in] p_data Pointer to the write data buffer
+ * \param[in] p_data_length Pointer to the length of the write data buffer
+ * \param[in,out] p_rx_buffer Pointer to the receive data buffer
+ * \param[in,out] p_rx_buffer_len Pointer to the length of the receive data buffer
+ *
+ * \retval #IFX_I2C_STACK_SUCCESS
+ * \retval #IFX_I2C_STACK_ERROR
+ * \retval #IFX_I2C_STACK_MEM_ERROR
+ */
+host_lib_status_t ifx_i2c_transceive(ifx_i2c_context_t *p_ctx,const uint8_t* p_data, const uint16_t* p_data_length,
+ uint8_t* p_rx_buffer, uint16_t* p_rx_buffer_len)
+{
+ host_lib_status_t api_status = (int32_t)IFX_I2C_STACK_ERROR;
+ // Proceed, if not busy and in idle state
+ if ((IFX_I2C_STATE_IDLE == p_ctx->state) && (IFX_I2C_STATUS_BUSY != p_ctx->status))
+ {
+ p_ctx->p_upper_layer_rx_buffer = p_rx_buffer;
+ p_ctx->p_upper_layer_rx_buffer_len = p_rx_buffer_len;
+ api_status = ifx_i2c_tl_transceive(p_ctx,(uint8_t*)p_data, (*p_data_length),
+ (uint8_t*)p_rx_buffer , p_rx_buffer_len);
+ if (IFX_I2C_STACK_SUCCESS == api_status)
+ {
+ p_ctx->status = IFX_I2C_STATUS_BUSY;
+ }
+ }
+ return api_status;
+}
+
+
+/**
+ * Closes the IFX I2C protocol stack for a given context.
+ * <br>
+ * <br>
+ * \image html ifx_i2c_close.png "ifx_i2c_close()" width=20cm
+ *
+ *<b>Pre Conditions:</b>
+ * - None<br>
+ *
+ *<b>API Details:</b>
+ * - De-Initializes the I2C slave device.<br>
+ * - Power downs the I2C slave.<br>
+ *<br>
+ *
+ *<b>User Input:</b><br>
+ * - The input #ifx_i2c_context_t p_ctx must not be NULL.
+ *
+ *<b>Notes:</b>
+ *
+ * \param[in,out] p_ctx Pointer to #ifx_i2c_context_t
+ *
+ * \retval #IFX_I2C_STACK_SUCCESS
+ */
+host_lib_status_t ifx_i2c_close(ifx_i2c_context_t *p_ctx)
+{
+ host_lib_status_t api_status = (int32_t)IFX_I2C_STACK_ERROR;
+ // Proceed, if not busy and in idle state
+ if (IFX_I2C_STATUS_BUSY != p_ctx->status)
+ {
+ api_status = IFX_I2C_STACK_SUCCESS;
+ //lint --e{534} suppress "Return value is not required to be checked"
+ // Close I2C master
+ pal_i2c_deinit(p_ctx->p_pal_i2c_ctx);
+ // Also power off the device
+ pal_gpio_set_low(p_ctx->p_slave_vdd_pin);
+ pal_gpio_set_low(p_ctx->p_slave_reset_pin);
+
+ ifx_i2c_tl_event_handler(p_ctx,IFX_I2C_STACK_SUCCESS,NULL,0);
+ p_ctx->state = IFX_I2C_STATE_UNINIT;
+ p_ctx->status = IFX_I2C_STATUS_NOT_BUSY;
+ }
+ return api_status;
+}
+
+/**
+* Writes new I2C slave Address to the target device.<br>
+*
+*<b>Pre Conditions:</b>
+* - IFX I2C protocol stack must be initialized.<br>
+*
+*<b>API Details:</b>
+* - This API is implemented in synchronous mode.
+* - If the write fails due to the following reasons, this API repeats the write for #PL_POLLING_MAX_CNT times
+* with a fixed interval of #PL_POLLING_INVERVAL_US microseconds and exits with respective return status.
+* - I2C bus is in busy state, returns #IFX_I2C_STACK_BUSY
+* - No-acknowledge(NACK) received from slave, returns #IFX_I2C_STACK_ERROR
+* - I2C errors, returns #IFX_I2C_STACK_ERROR
+* - Only bits [6:0] from parameter "slave_address" are considered as slave address. Hence the bit 7 is ignored.
+* - Slave address validation is not done in the implementation. Provide a valid slave address as input.
+*
+*<b>Notes:</b>
+* - If persistent mode is selected, the ifx i2c context slave address will be over-written with the new slave address.
+* Even after ifx i2c open/reset, all future executions will use the new slave address.<br>
+* - If volatile mode is selected, the pal_i2c_context slave address will be over-written with the new slave address.
+* This persists only till the next ifx_i2c open/reset is called.
+*
+* \param[in,out] p_ctx Pointer to #ifx_i2c_context_t
+* \param[in] slave_address Holds new slave address[7 Bit] to be set.
+* \param[in] persistent 0 - To set the Slave address until next reset.<br>
+* Non-zero - To set the slave address to persistent memory.
+*
+* \retval #IFX_I2C_STACK_SUCCESS
+* \retval #IFX_I2C_STACK_ERROR
+*/
+host_lib_status_t ifx_i2c_set_slave_address(ifx_i2c_context_t *p_ctx, uint8_t slave_address, uint8_t persistent)
+{
+ host_lib_status_t api_status = (int32_t)IFX_I2C_STACK_ERROR;
+
+ if ((IFX_I2C_STATE_IDLE == p_ctx->state))
+ {
+ p_ctx->p_pal_i2c_ctx->upper_layer_ctx = p_ctx;
+
+ api_status = ifx_i2c_pl_write_slave_address(p_ctx, slave_address, persistent);
+ }
+
+ return api_status;
+}
+
+/// @cond hidden
+//lint --e{715} suppress "This is ignored as ifx_i2c_event_handler_t handler function prototype requires this argument"
+void ifx_i2c_tl_event_handler(ifx_i2c_context_t* p_ctx,host_lib_status_t event, const uint8_t* p_data, uint16_t data_len)
+{
+ // If there is no upper layer handler, don't do anything and return
+ if (NULL != p_ctx->upper_layer_event_handler)
+ {
+ p_ctx->upper_layer_event_handler(p_ctx->p_upper_layer_ctx,event);
+ }
+ p_ctx->status = IFX_I2C_STATUS_NOT_BUSY;
+ switch(p_ctx->state)
+ {
+ case IFX_I2C_STATE_UNINIT:
+ if (IFX_I2C_STACK_SUCCESS == event)
+ {
+ p_ctx->state = IFX_I2C_STATE_IDLE;
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+
+static host_lib_status_t ifx_i2c_init(ifx_i2c_context_t* p_ifx_i2c_context)
+{
+ host_lib_status_t api_status = IFX_I2C_STACK_ERROR;
+
+ if ((p_ifx_i2c_context->reset_type == (uint8_t)IFX_I2C_WARM_RESET)||
+ (p_ifx_i2c_context->reset_type == (uint8_t)IFX_I2C_COLD_RESET))
+ {
+ switch(p_ifx_i2c_context->reset_state)
+ {
+ case IFX_I2C_STATE_RESET_PIN_LOW:
+ // Setting the Vdd & Reset pin to low
+ if (p_ifx_i2c_context->reset_type == (uint8_t)IFX_I2C_COLD_RESET)
+ {
+ pal_gpio_set_low(p_ifx_i2c_context->p_slave_vdd_pin);
+ }
+ pal_gpio_set_low(p_ifx_i2c_context->p_slave_reset_pin);
+ p_ifx_i2c_context->reset_state = IFX_I2C_STATE_RESET_PIN_HIGH;
+ pal_os_event_register_callback_oneshot((register_callback)ifx_i2c_init,
+ (void *)p_ifx_i2c_context, RESET_LOW_TIME_MSEC);
+ api_status = IFX_I2C_STACK_SUCCESS;
+ break;
+
+ case IFX_I2C_STATE_RESET_PIN_HIGH:
+ // Setting the Vdd & Reset pin to high
+ if (p_ifx_i2c_context->reset_type == (uint8_t)IFX_I2C_COLD_RESET)
+ {
+ pal_gpio_set_high(p_ifx_i2c_context->p_slave_vdd_pin);
+ }
+ pal_gpio_set_high(p_ifx_i2c_context->p_slave_reset_pin);
+ p_ifx_i2c_context->reset_state = IFX_I2C_STATE_RESET_INIT;
+ pal_os_event_register_callback_oneshot((register_callback)ifx_i2c_init,
+ (void *)p_ifx_i2c_context, STARTUP_TIME_MSEC);
+ api_status = IFX_I2C_STACK_SUCCESS;
+ break;
+
+ case IFX_I2C_STATE_RESET_INIT:
+ //Frequency and frame size negotiation
+ api_status = ifx_i2c_tl_init(p_ifx_i2c_context,ifx_i2c_tl_event_handler);
+ break;
+ default:
+ break;
+ }
+ }
+ //soft reset
+ else
+ {
+ p_ifx_i2c_context->pl.request_soft_reset = (uint8_t)TRUE; //Soft reset
+ api_status = ifx_i2c_tl_init(p_ifx_i2c_context,ifx_i2c_tl_event_handler);
+ }
+
+ return api_status;
+}
+/// @endcond
+/**
+* @}
+*/
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/optiga_comms/ifx_i2c/ifx_i2c_config.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/optiga_comms/ifx_i2c/ifx_i2c_config.c
new file mode 100644
index 0000000..92cafb2
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/optiga_comms/ifx_i2c/ifx_i2c_config.c
@@ -0,0 +1,68 @@
+/**
+* \copyright
+* Copyright (c) 2018, Infineon Technologies AG
+* All rights reserved.
+*
+* This software is provided with terms and conditions as specified in OPTIGA(TM) Trust X Evaluation Kit License Agreement.
+* \endcopyright
+*
+* \author Infineon AG
+*
+* \file ifx_i2c_config.c
+*
+* \brief This file provides the ifx i2c platform specific context configurations.
+*
+* \addtogroup grIFXI2C
+* @{
+*/
+
+/***********************************************************************************************************************
+* HEADER FILES
+**********************************************************************************************************************/
+// Protocol Stack Includes
+#include "pal_ifx_i2c_config.h"
+#include "ifx_i2c_config.h"
+
+/***********************************************************************************************************************
+* MACROS
+**********************************************************************************************************************/
+
+
+/***********************************************************************************************************************
+* ENUMS
+**********************************************************************************************************************/
+/***********************************************************************************************************************
+* DATA STRUCTURES
+***********************************************************************************************************************/
+
+/** @brief This is IFX I2C context. Only one context is supported per slave.*/
+//lint --e{785} suppress "Only required fields are initialized, the rest are handled by consumer of this structure"
+ifx_i2c_context_t ifx_i2c_context_0 =
+{
+ /// Slave address
+ 0x30,
+ /// i2c-master frequency
+ 400,
+ /// IFX-I2C frame size
+ 0x3B,
+ /// Vdd pin
+ &optiga_vdd_0,
+ /// Reset pin
+ &optiga_reset_0,
+ /// optiga pal i2c context
+ &optiga_pal_i2c_context_0
+};
+
+/***********************************************************************************************************************
+* GLOBAL
+***********************************************************************************************************************/
+/***********************************************************************************************************************
+* LOCAL ROUTINES
+***********************************************************************************************************************/
+/***********************************************************************************************************************
+* API PROTOTYPES
+**********************************************************************************************************************/
+
+/**
+ * @}
+ **/
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/optiga_comms/ifx_i2c/ifx_i2c_data_link_layer.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/optiga_comms/ifx_i2c/ifx_i2c_data_link_layer.c
new file mode 100644
index 0000000..aea960c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/optiga_comms/ifx_i2c/ifx_i2c_data_link_layer.c
@@ -0,0 +1,568 @@
+/**
+* \copyright
+* Copyright (c) 2018, Infineon Technologies AG
+* All rights reserved.
+*
+* This software is provided with terms and conditions as specified in OPTIGA(TM) Trust X Evaluation Kit License Agreement.
+* \endcopyright
+*
+* \author Infineon AG
+*
+* \file ifx_i2c_data_link_layer.c
+*
+* \brief This file implements the IFX I2C Datalink Layer.
+*
+* \addtogroup grIFXI2C
+* @{
+*/
+
+/***********************************************************************************************************************
+* HEADER FILES
+**********************************************************************************************************************/
+#include "ifx_i2c_data_link_layer.h"
+#include "ifx_i2c_physical_layer.h" // include lower layer header
+
+/// @cond hidden
+/***********************************************************************************************************************
+* MACROS
+**********************************************************************************************************************/
+// Data Link layer internal states
+#define DL_STATE_UNINIT (0x00)
+#define DL_STATE_IDLE (0x01)
+#define DL_STATE_TX (0x02)
+#define DL_STATE_RX (0x03)
+#define DL_STATE_ACK (0x04)
+#define DL_STATE_RESEND (0x05)
+#define DL_STATE_NACK (0x06)
+#define DL_STATE_ERROR (0x08)
+#define DL_STATE_DISCARD (0x09)
+#define DL_STATE_RX_DF (0x0A)
+#define DL_STATE_RX_CF (0x0B)
+
+// Data Link Layer Frame Control Constants
+#define DL_FCTR_FTYPE_MASK (0x80)
+#define DL_FCTR_FTYPE_OFFSET (7)
+#define DL_FCTR_VALUE_CONTROL_FRAME (0x01)
+
+#define DL_FCTR_SEQCTR_MASK (0x60)
+#define DL_FCTR_SEQCTR_OFFSET (5)
+#define DL_FCTR_SEQCTR_VALUE_ACK (0x00)
+#define DL_FCTR_SEQCTR_VALUE_NACK (0x01)
+#define DL_FCTR_SEQCTR_VALUE_RESYNC (0x02)
+#define DL_FCTR_SEQCTR_VALUE_RFU (0x03)
+
+#define DL_FCTR_FRNR_MASK (0x0C)
+#define DL_FCTR_FRNR_OFFSET (2)
+
+#define DL_FCTR_ACKNR_MASK (0x03)
+#define DL_FCTR_ACKNR_OFFSET (0)
+
+// Data Link Layer frame counter max value
+#define DL_MAX_FRAME_NUM (0x03)
+
+// Data link layer length
+#define DL_CONTROL_FRAME_LENGTH (5)
+
+// Setup debug log statements
+#if IFX_I2C_LOG_DL == 1
+#define LOG_DL IFX_I2C_LOG
+#else
+#define LOG_DL(...) //printf(__VA_ARGS__)
+#endif
+
+
+/***********************************************************************************************************************
+* ENUMS
+**********************************************************************************************************************/
+/***********************************************************************************************************************
+* DATA STRUCTURES
+***********************************************************************************************************************/
+/***********************************************************************************************************************
+* GLOBAL
+***********************************************************************************************************************/
+/***********************************************************************************************************************
+* LOCAL ROUTINES
+***********************************************************************************************************************/
+/// Helper function to calculate CRC of a byte
+_STATIC_H host_lib_status_t ifx_i2c_dl_calc_crc_byte(uint16_t wSeed, uint8_t bByte);
+/// Helper function to calculate CRC of a frame
+_STATIC_H host_lib_status_t ifx_i2c_dl_calc_crc(const uint8_t* p_data, uint16_t data_len);
+/// Internal function to send frame
+_STATIC_H host_lib_status_t ifx_i2c_dl_send_frame_internal(ifx_i2c_context_t *p_ctx,uint16_t frame_len,uint8_t seqctr_value, uint8_t resend);
+/// Helper function to send resync
+_STATIC_H host_lib_status_t ifx_i2c_dl_resync(ifx_i2c_context_t* p_ctx);
+/// Helper function to resend frame
+_STATIC_H void ifx_i2c_dl_resend_frame(ifx_i2c_context_t* p_ctx,uint8_t seqctr_value);
+/// Data Link Layer state machine
+_STATIC_H void ifx_i2c_pl_event_handler(ifx_i2c_context_t* p_ctx,host_lib_status_t event, const uint8_t* p_data, uint16_t data_len);
+
+/// @endcond
+/***********************************************************************************************************************
+* API PROTOTYPES
+**********************************************************************************************************************/
+host_lib_status_t ifx_i2c_dl_init(ifx_i2c_context_t *p_ctx,ifx_i2c_event_handler_t handler)
+{
+ LOG_DL("[IFX-DL]: Init\n");
+
+ p_ctx->dl.state = DL_STATE_UNINIT;
+ // Initialize Physical Layer (and register event handler)
+ if (ifx_i2c_pl_init(p_ctx, ifx_i2c_pl_event_handler) != IFX_I2C_STACK_SUCCESS)
+ {
+ return IFX_I2C_STACK_ERROR;
+ }
+
+ // Initialize internal variables
+ p_ctx->dl.upper_layer_event_handler = handler;
+ p_ctx->dl.state = DL_STATE_IDLE;
+ p_ctx->dl.tx_seq_nr = DL_MAX_FRAME_NUM;
+ p_ctx->dl.rx_seq_nr = DL_MAX_FRAME_NUM;
+ p_ctx->dl.resynced = 0;
+ p_ctx->dl.error = 0;
+ p_ctx->dl.p_tx_frame_buffer = p_ctx->tx_frame_buffer;
+ p_ctx->dl.p_rx_frame_buffer = p_ctx->rx_frame_buffer;
+
+ return IFX_I2C_STACK_SUCCESS;
+}
+
+host_lib_status_t ifx_i2c_dl_send_frame(ifx_i2c_context_t *p_ctx,uint16_t frame_len)
+{
+ LOG_DL("[IFX-DL]: Start TX Frame\n");
+ // State must be idle and payload available
+ if (p_ctx->dl.state != DL_STATE_IDLE || !frame_len)
+ {
+ return IFX_I2C_STACK_ERROR;
+ }
+
+ p_ctx->dl.state = DL_STATE_TX;
+ p_ctx->dl.retransmit_counter = 0;
+ p_ctx->dl.action_rx_only = 0;
+ p_ctx->dl.tx_buffer_size = frame_len;
+ p_ctx->dl.data_poll_timeout = PL_TRANS_TIMEOUT_MS;
+
+ return ifx_i2c_dl_send_frame_internal(p_ctx,frame_len, DL_FCTR_SEQCTR_VALUE_ACK, 0);
+}
+
+host_lib_status_t ifx_i2c_dl_receive_frame(ifx_i2c_context_t *p_ctx)
+{
+ LOG_DL("[IFX-DL]: Start RX Frame\n");
+
+ if (p_ctx->dl.state != DL_STATE_IDLE)
+ {
+ return IFX_I2C_STACK_ERROR;
+ }
+
+ // Set internal state
+ p_ctx->dl.state = DL_STATE_RX;
+ p_ctx->dl.retransmit_counter = 0;
+ p_ctx->dl.action_rx_only = 1;
+ p_ctx->dl.frame_start_time = pal_os_timer_get_time_in_milliseconds();
+ p_ctx->dl.data_poll_timeout = TL_MAX_EXIT_TIMEOUT*1000;
+
+ return ifx_i2c_pl_receive_frame(p_ctx);
+}
+
+_STATIC_H host_lib_status_t ifx_i2c_dl_calc_crc_byte(uint16_t wSeed, uint8_t bByte)
+{
+ uint16_t wh1;
+ uint16_t wh2;
+ uint16_t wh3;
+ uint16_t wh4;
+
+ wh1 = (wSeed ^ bByte) & 0xFF;
+ wh2 = wh1 & 0x0F;
+ wh3 = ((uint16_t)(wh2 << 4)) ^ wh1;
+ wh4 = wh3 >> 4;
+
+ return ((uint16_t)((((uint16_t)((((uint16_t)(wh3 << 1)) ^ wh4) << 4)) ^ wh2) << 3)) ^ wh4
+ ^ (wSeed >> 8);
+}
+
+_STATIC_H host_lib_status_t ifx_i2c_dl_calc_crc(const uint8_t* p_data, uint16_t data_len)
+{
+ uint16_t i;
+ uint16_t crc = 0;
+
+ for (i = 0; i < data_len; i++)
+ {
+ crc = ifx_i2c_dl_calc_crc_byte(crc, p_data[i]);
+ }
+
+ return crc;
+}
+
+_STATIC_H host_lib_status_t ifx_i2c_dl_send_frame_internal(ifx_i2c_context_t *p_ctx,uint16_t frame_len,
+ uint8_t seqctr_value, uint8_t resend)
+{
+ uint16_t crc;
+ uint16_t ack_nr = p_ctx->dl.rx_seq_nr;
+ uint8_t* p_buffer;
+
+ LOG_DL("[IFX-DL]: TX Frame len %d\n", frame_len);
+ // In case of sending a NACK the next frame is referenced
+ if (seqctr_value == DL_FCTR_SEQCTR_VALUE_NACK)
+ {
+ ack_nr = (p_ctx->dl.rx_seq_nr + 1) & DL_MAX_FRAME_NUM;
+ }
+ if(seqctr_value == DL_FCTR_SEQCTR_VALUE_RESYNC)
+ {
+ ack_nr = 0;
+ // Use rx buffer to send resync
+ p_buffer = p_ctx->dl.p_rx_frame_buffer;
+ }
+ else
+ {
+ p_buffer = p_ctx->dl.p_tx_frame_buffer;
+ }
+ // Set sequence control value (ACK or NACK) and referenced frame number
+ p_buffer[0] = (uint8_t)(ack_nr << DL_FCTR_ACKNR_OFFSET);
+ p_buffer[0] |= (uint8_t)(seqctr_value << DL_FCTR_SEQCTR_OFFSET);
+
+ if (frame_len) // Data frame
+ {
+ // Increment and set frame transmit sequence number
+ if ((!resend)||(p_ctx->dl.resynced))
+ {
+ p_ctx->dl.tx_seq_nr = (p_ctx->dl.tx_seq_nr + 1) & DL_MAX_FRAME_NUM;
+ }
+ p_buffer[0] |= (uint8_t)(p_ctx->dl.tx_seq_nr << DL_FCTR_FRNR_OFFSET);
+ // Reset resync received
+ p_ctx->dl.resynced = 0;
+ }
+ else // Control frame
+ {
+ p_buffer[0] |= DL_FCTR_FTYPE_MASK;
+ }
+
+ // Set frame length
+ p_buffer[1] = (uint8_t)(frame_len >> 8);
+ p_buffer[2] = (uint8_t)frame_len;
+
+ // Calculate frame CRC
+ crc = ifx_i2c_dl_calc_crc(p_buffer, 3 + frame_len);
+ p_buffer[3 + frame_len] = (uint8_t) (crc >> 8);
+ p_buffer[4 + frame_len] = (uint8_t)crc;
+
+ // Transmit frame
+ return ifx_i2c_pl_send_frame(p_ctx,p_buffer, DL_HEADER_SIZE + frame_len);
+}
+
+_STATIC_H host_lib_status_t ifx_i2c_dl_resync(ifx_i2c_context_t* p_ctx)
+{
+ host_lib_status_t api_status = IFX_I2C_STACK_SUCCESS;
+ // Reset tx and rx counters
+ p_ctx->dl.tx_seq_nr = DL_MAX_FRAME_NUM;
+ p_ctx->dl.rx_seq_nr = DL_MAX_FRAME_NUM;
+ p_ctx->dl.resynced = 1;
+ LOG_DL("[IFX-DL]: Send Re-Sync Frame\n");
+ p_ctx->dl.state = DL_STATE_RESEND;
+ api_status = ifx_i2c_dl_send_frame_internal(p_ctx,0,DL_FCTR_SEQCTR_VALUE_RESYNC,0);
+ return api_status;
+}
+
+_STATIC_H void ifx_i2c_dl_resend_frame(ifx_i2c_context_t* p_ctx,uint8_t seqctr_value)
+{
+ host_lib_status_t status;
+ // If exit timeout not violated
+ uint32_t current_time_stamp = pal_os_timer_get_time_in_milliseconds();
+ if ((current_time_stamp - p_ctx->tl.api_start_time) < (TL_MAX_EXIT_TIMEOUT * 1000))
+ {
+ if(p_ctx->dl.retransmit_counter == DL_TRANS_REPEAT)
+ {
+ LOG_DL("[IFX-DL]: Re-Sync counters\n");
+ p_ctx->dl.retransmit_counter = 0;
+ status = ifx_i2c_dl_resync(p_ctx);
+ }
+ else
+ {
+ LOG_DL("[IFX-DL]: Re-TX Frame\n");
+ p_ctx->dl.retransmit_counter++;
+ p_ctx->dl.state = DL_STATE_TX;
+ status = ifx_i2c_dl_send_frame_internal(p_ctx,p_ctx->dl.tx_buffer_size,seqctr_value, 1);
+ }
+ // Handle error in above case by sending NACK
+ if (IFX_I2C_STACK_SUCCESS != status)
+ {
+ p_ctx->dl.state = DL_STATE_NACK;
+ }
+ }
+ else
+ {
+ p_ctx->dl.state = DL_STATE_ERROR;
+ }
+}
+
+_STATIC_H void ifx_i2c_pl_event_handler(ifx_i2c_context_t* p_ctx,host_lib_status_t event, const uint8_t* p_data, uint16_t data_len)
+{
+ uint8_t fctr = 0;
+ uint8_t fr_nr = 0;
+ uint8_t ack_nr = 0;
+ uint8_t seqctr = 0;
+ uint8_t current_event;
+ uint8_t ftype;
+ uint8_t continue_state_machine = TRUE;
+ uint16_t packet_len = 0;
+ uint16_t crc_received = 0;
+ uint16_t crc_calculated = 0;
+ LOG_DL("[IFX-DL]: #Enter DL Handler\n");
+ do
+ {
+ if((event == IFX_I2C_FATAL_ERROR) && (DL_STATE_IDLE != p_ctx->dl.state))
+ { // Exit in case of fatal error
+ LOG_DL("[IFX-DL]: Fatal error received\n");
+ p_ctx->dl.state = DL_STATE_ERROR;
+ }
+ switch(p_ctx->dl.state)
+ {
+ case DL_STATE_IDLE:
+ {
+ current_event = (event != IFX_I2C_STACK_SUCCESS)?IFX_I2C_DL_EVENT_ERROR:IFX_I2C_DL_EVENT_TX_SUCCESS;
+ continue_state_machine = FALSE;
+ p_ctx->dl.upper_layer_event_handler(p_ctx,current_event, 0, 0);
+ }
+ break;
+ case DL_STATE_TX:
+ {
+ // If writing a frame failed retry sending
+ if (event == IFX_I2C_STACK_ERROR)
+ {
+ p_ctx->dl.state = DL_STATE_RESEND;
+ break;
+ }
+ LOG_DL("[IFX-DL]: Frame Sent\n");
+ // Transmission successful, start receiving frame
+ p_ctx->dl.frame_start_time = pal_os_timer_get_time_in_milliseconds();
+ p_ctx->dl.state = DL_STATE_RX;
+ if (ifx_i2c_pl_receive_frame(p_ctx))
+ {
+ p_ctx->dl.state = DL_STATE_NACK;
+ }
+ else
+ {
+ continue_state_machine = FALSE;
+ }
+ }
+ break;
+ case DL_STATE_RX:
+ {
+ if (event == IFX_I2C_STACK_ERROR)
+ { // If no frame was received retry sending
+ p_ctx->dl.state = DL_STATE_RESEND;
+ break;
+ }
+ // Received frame from device, start analyzing
+ LOG_DL("[IFX-DL]: Received Frame of length %d\n",data_len);
+
+ if (data_len < DL_HEADER_SIZE)
+ { // Received length is less than minimum size
+ LOG_DL("[IFX-DL]: received data_len < DL_HEADER_SIZE\n");
+ p_ctx->dl.state = DL_STATE_NACK;
+ break;
+ }
+ // Check transmit frame sequence number
+ fctr = p_data[0];
+ ftype = (fctr & DL_FCTR_FTYPE_MASK) >> DL_FCTR_FTYPE_OFFSET;
+ seqctr = (fctr & DL_FCTR_SEQCTR_MASK) >> DL_FCTR_SEQCTR_OFFSET;
+ ack_nr = (fctr & DL_FCTR_ACKNR_MASK) >> DL_FCTR_ACKNR_OFFSET;
+ fr_nr = (fctr & DL_FCTR_FRNR_MASK) >> DL_FCTR_FRNR_OFFSET;
+ packet_len = (p_data[1] << 8) | p_data[2];
+
+ // Check frame CRC value
+ crc_received = (p_data[data_len - 2] << 8) | p_data[data_len - 1];
+ crc_calculated = ifx_i2c_dl_calc_crc(p_data, data_len - 2);
+ p_ctx->dl.state = (ftype == DL_FCTR_VALUE_CONTROL_FRAME)?DL_STATE_RX_CF:DL_STATE_RX_DF;
+ }
+ break;
+ case DL_STATE_RX_DF:
+ {
+ LOG_DL("[IFX-DL]: Data Frame Received\n");
+ if ((crc_received != crc_calculated)||(packet_len == 0)||(data_len != DL_HEADER_SIZE + packet_len)||
+ (seqctr == DL_FCTR_SEQCTR_VALUE_RFU) || (seqctr == DL_FCTR_SEQCTR_VALUE_RESYNC))
+ {
+ // CRC,Length of data frame is 0/ SEQCTR has RFU/Re-sync in Data frame
+ LOG_DL("[IFX-DL]: NACK for CRC error,Data frame length is not correct,RFU in SEQCTR\n");
+ p_ctx->dl.state = DL_STATE_NACK;
+ break;
+ }
+ if (fr_nr != ((p_ctx->dl.rx_seq_nr + 1) & DL_MAX_FRAME_NUM))
+ {
+ LOG_DL("[IFX-DL]: Data frame number not expected\n");
+ p_ctx->dl.state = DL_STATE_DISCARD;
+ continue_state_machine = FALSE;
+ //lint --e{534} suppress "Return value is not required to be checked"
+ ifx_i2c_dl_send_frame_internal(p_ctx,0, DL_FCTR_SEQCTR_VALUE_ACK, 0);
+ break;
+ }
+ if (ack_nr != p_ctx->dl.tx_seq_nr)
+ {
+ // ack number error
+ LOG_DL("[IFX-DL]: Error in ack number\n");
+ //lint --e{534} suppress "Return value is not required to be checked"
+ p_ctx->dl.state = DL_STATE_DISCARD;
+ break;
+ }
+ if (seqctr == DL_FCTR_SEQCTR_VALUE_NACK)
+ {
+ // NACK for transmitted frame
+ LOG_DL("[IFX-DL]: NACK received in data frame\n");
+ p_ctx->dl.state = DL_STATE_RESEND;
+ break;
+ }
+ p_ctx->dl.rx_seq_nr = (p_ctx->dl.rx_seq_nr + 1) & DL_MAX_FRAME_NUM;
+ memcpy(p_ctx->dl.p_rx_frame_buffer, p_data, data_len);
+ p_ctx->dl.rx_buffer_size = data_len;
+
+ // Send control frame to acknowledge reception of this data frame
+ LOG_DL("[IFX-DL]: Read Data Frame -> Send ACK\n");
+ p_ctx->dl.retransmit_counter = 0;
+ p_ctx->dl.state = DL_STATE_ACK;
+ continue_state_machine = FALSE;
+ //lint --e{534} suppress "Return value is not required to be checked"
+ ifx_i2c_dl_send_frame_internal(p_ctx,0, DL_FCTR_SEQCTR_VALUE_ACK, 0);
+ }
+ break;
+ case DL_STATE_RX_CF:
+ {
+ LOG_DL("[IFX-DL]: Control Frame Received\n");
+ // Discard Control frame when in receiver mode except for Re-Sync
+ //lint --e{514} suppress "The check is intended to be done this way"
+ if((p_ctx->dl.action_rx_only) ^ (seqctr == DL_FCTR_SEQCTR_VALUE_RESYNC))
+ {
+ //If control frame already received for data frame, ignore any received control frame
+ LOG_DL("[IFX-DL]: CF in receiver mode,Discard\n");
+ p_ctx->dl.state = DL_STATE_DISCARD;
+ break;
+ }
+ if (crc_received != crc_calculated)
+ {
+ // Re-Transmit frame in case of CF CRC error
+ LOG_DL("[IFX-DL]: Retransmit frame for CF CRC error\n");
+ p_ctx->dl.state = DL_STATE_RESEND;
+ break;
+ }
+ if((data_len > DL_CONTROL_FRAME_LENGTH)||(packet_len != 0))
+ {
+ // Control frame is more than 5/Control frame with non-zero FRNR/packet len is not 0
+ LOG_DL("[IFX-DL]: Errors in control frame\n");
+ p_ctx->dl.state = DL_STATE_DISCARD;
+ break;
+ }
+ if(seqctr == DL_FCTR_SEQCTR_VALUE_RESYNC)
+ { // Re-sync received
+ LOG_DL("[IFX-DL]: Re-Sync received\n");
+ p_ctx->dl.state = DL_STATE_DISCARD;
+ p_ctx->dl.resynced = 1;
+ p_ctx->dl.tx_seq_nr = DL_MAX_FRAME_NUM;
+ p_ctx->dl.rx_seq_nr = DL_MAX_FRAME_NUM;
+ break;
+ }
+ if((fr_nr!=0)||(seqctr == DL_FCTR_SEQCTR_VALUE_RFU)||(ack_nr != p_ctx->dl.tx_seq_nr))
+ {
+ // Control frame with non-zero FRNR/ ACK not received/ ack number != tx number
+ LOG_DL("[IFX-DL]: Errors in control frame\n");
+ p_ctx->dl.state = DL_STATE_DISCARD;
+ break;
+ }
+ if (seqctr == DL_FCTR_SEQCTR_VALUE_NACK)
+ {
+ // NACK for transmitted frame
+ LOG_DL("[IFX-DL]: NACK received\n");
+ p_ctx->dl.state = DL_STATE_RESEND;
+ break;
+ }
+
+ LOG_DL("[IFX-DL]: ACK received\n");
+ // Report frame reception to upper layer and go in idle state
+ p_ctx->dl.state = DL_STATE_IDLE;
+ continue_state_machine = FALSE;
+ p_ctx->dl.upper_layer_event_handler(p_ctx,IFX_I2C_DL_EVENT_TX_SUCCESS, 0, 0);
+ }
+ break;
+ case DL_STATE_DISCARD:
+ {
+ LOG_DL("[IFX-DL]: Discard frame\n");
+ p_ctx->dl.state = DL_STATE_RX;
+ continue_state_machine = FALSE;
+ //lint --e{534} suppress "Return value is not required to be checked"
+ ifx_i2c_pl_receive_frame(p_ctx);
+ }
+ break;
+ case DL_STATE_ACK:
+ {
+ LOG_DL("[IFX-DL]: ACK sent\n");
+ if (event == IFX_I2C_STACK_ERROR)
+ {
+ // If writing the ACK frame failed, Re-Send
+ LOG_DL("[IFX-DL]: Physical Layer error -> Resend ACK\n");
+ p_ctx->dl.state = DL_STATE_RESEND;
+ break;
+ }
+ // Control frame successful transmitted
+ p_ctx->dl.state = DL_STATE_IDLE;
+ continue_state_machine = FALSE;
+ if (p_ctx->dl.action_rx_only)
+ {
+ p_ctx->dl.upper_layer_event_handler(p_ctx,IFX_I2C_DL_EVENT_RX_SUCCESS, p_ctx->dl.p_rx_frame_buffer + 3,
+ p_ctx->dl.rx_buffer_size - DL_HEADER_SIZE);
+ }
+ else
+ {
+ p_ctx->dl.upper_layer_event_handler(p_ctx,IFX_I2C_DL_EVENT_TX_SUCCESS | IFX_I2C_DL_EVENT_RX_SUCCESS,
+ p_ctx->dl.p_rx_frame_buffer + 3, p_ctx->dl.rx_buffer_size - DL_HEADER_SIZE);
+ }
+ }
+ break;
+ case DL_STATE_NACK:
+ {
+ // Sending NACK
+ LOG_DL("[IFX-DL]: Sending NACK\n");
+ p_ctx->dl.state = DL_STATE_TX;
+ continue_state_machine = FALSE;
+ //lint --e{534} suppress "Return value is not required to be checked"
+ ifx_i2c_dl_send_frame_internal(p_ctx,0, DL_FCTR_SEQCTR_VALUE_NACK, 0);
+ }
+ break;
+ case DL_STATE_RESEND:
+ {
+ //Resend frame
+ ifx_i2c_dl_resend_frame(p_ctx,DL_FCTR_SEQCTR_VALUE_ACK);
+ if(p_ctx->dl.state != DL_STATE_ERROR)
+ {
+ continue_state_machine = FALSE;
+ }
+ }
+ break;
+ case DL_STATE_ERROR:
+ {
+ if(!p_ctx->dl.resynced)
+ {
+ p_ctx->dl.error = 1;
+ }
+ if(0 == p_ctx->dl.error)
+ {
+ LOG_DL("[IFX-DL]: Exit error after fatal error\n");
+ //After sending resync, inform upper layer
+ p_ctx->dl.state = DL_STATE_IDLE;
+ p_ctx->dl.upper_layer_event_handler(p_ctx,IFX_I2C_DL_EVENT_ERROR, 0, 0);
+ }
+ else
+ {
+ LOG_DL("[IFX-DL]: Sending re-sync after fatal error\n");
+ // Send re-sync to slave on error
+ //lint --e{534} suppress "As this is last step, no effect of checking return code"
+ ifx_i2c_dl_resync(p_ctx);
+ p_ctx->dl.state = DL_STATE_ERROR;
+ p_ctx->dl.error = 0;
+ }
+ continue_state_machine = FALSE;
+ }
+ break;
+ default:
+ LOG_DL("[IFX-DL]: Default condition occurred. Exiting with error\n");
+ p_ctx->dl.state = DL_STATE_IDLE;
+ p_ctx->dl.upper_layer_event_handler(p_ctx,IFX_I2C_DL_EVENT_ERROR, 0, 0);
+ continue_state_machine = FALSE;
+ break;
+ }
+ }while(continue_state_machine == TRUE);
+ LOG_DL("[IFX-DL]: #Exiting DL Handler\n");
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/optiga_comms/ifx_i2c/ifx_i2c_physical_layer.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/optiga_comms/ifx_i2c/ifx_i2c_physical_layer.c
new file mode 100644
index 0000000..8067685
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/optiga_comms/ifx_i2c/ifx_i2c_physical_layer.c
@@ -0,0 +1,742 @@
+/**
+* \copyright
+* Copyright (c) 2018, Infineon Technologies AG
+* All rights reserved.
+*
+* This software is provided with terms and conditions as specified in OPTIGA(TM) Trust X Evaluation Kit License Agreement.
+* \endcopyright
+*
+* \author Infineon AG
+*
+* \file ifx_i2c_physical_layer.c
+*
+* \brief This file implements the IFX I2C Physical Layer.
+*
+* \addtogroup grIFXI2C
+* @{
+*/
+
+/***********************************************************************************************************************
+* HEADER FILES
+**********************************************************************************************************************/
+#include "ifx_i2c_physical_layer.h"
+#include "pal_os_event.h"
+
+/// @cond hidden
+/***********************************************************************************************************************
+* MACROS
+**********************************************************************************************************************/
+// Physical Layer Register addresses
+#define PL_REG_DATA (0x80)
+#define PL_REG_DATA_REG_LEN (0x81)
+#define PL_REG_I2C_STATE (0x82)
+#define PL_REG_BASE_ADDR (0x83)
+#define PL_REG_MAX_SCL_FREQU (0x84)
+#define PL_REG_SOFT_RESET (0x88)
+#define PL_REG_I2C_MODE (0x89)
+
+// Physical Layer Register lengths
+#define PL_REG_LEN_I2C_STATE (4)
+#define PL_REG_LEN_MAX_SCL_FREQU (4)
+#define PL_REG_LEN_I2C_MODE (2)
+#define PL_REG_LEN_DATA_REG_LEN (2)
+#define PL_REG_LEN_SOFT_RESET (2)
+#define PL_REG_LEN_BASE_ADDR (2)
+
+// Physical Layer State Register masks
+#define PL_REG_I2C_STATE_RESPONSE_READY (0x40)
+#define PL_REG_I2C_STATE_SOFT_RESET (0x08)
+
+// Physical Layer low level interface constants
+#define PL_ACTION_READ_REGISTER (0x01)
+#define PL_ACTION_WRITE_REGISTER (0x02)
+#define PL_I2C_CMD_WRITE (0x01)
+#define PL_I2C_CMD_READ (0x02)
+
+// Physical Layer high level interface constants
+#define PL_ACTION_WRITE_FRAME (0x01)
+#define PL_ACTION_READ_FRAME (0x02)
+#define PL_STATE_UNINIT (0x00)
+#define PL_STATE_INIT (0x01)
+#define PL_STATE_READY (0x02)
+#define PL_STATE_DATA_AVAILABLE (0x03)
+#define PL_STATE_RXTX (0x04)
+#define PL_STATE_SOFT_RESET (0x05)
+
+//Physical Layer negotiation constants
+#define PL_INIT_SET_DATA_REG_LEN (0x11)
+#define PL_INIT_GET_DATA_REG_LEN (0x22)
+#define PL_INIT_GET_FREQ_REG (0x33)
+#define PL_INIT_SET_FREQ_REG (0x44)
+#define PL_INIT_READ_FREQ (0x55)
+#define PL_INIT_VERIFY_FREQ (0x66)
+#define PL_INIT_AGREE_FREQ (0x77)
+#define PL_INIT_VERIFY_DATA_REG (0x88)
+#define PL_INIT_GET_STATUS_REG (0x99)
+#define PL_INIT_DONE (0xAA)
+#define PL_INIT_SET_FREQ_DEFAULT (0xBB)
+
+//Physical layer soft reset states
+#define PL_RESET_INIT (0xA1)
+#define PL_RESET_WRITE (0xA2)
+#define PL_RESET_STARTUP (0xA3)
+
+#define PL_REG_I2C_MODE_PERSISTANT (0x80)
+#define PL_REG_I2C_MODE_SM_FM (0x03)
+#define PL_REG_I2C_MODE_FM_PLUS (0x04)
+#define PL_SM_FM_MAX_FREQUENCY (0x190)
+#define PL_DEFAULT_FREQUENCY (0x64)
+#define PL_REG_BASE_ADDR_PERSISTANT (0x80)
+#define PL_REG_BASE_ADDR_VOLATILE (0x00)
+
+// Physical Layer Base Address Register mask
+#define PL_REG_I2C_BASE_ADDRESS_MASK (0x7F)
+
+// Setup debug log statements
+#if IFX_I2C_LOG_PL == 1
+#define LOG_PL IFX_I2C_LOG
+#else
+#define LOG_PL(...) //printf(__VA_ARGS__)
+#endif
+/***********************************************************************************************************************
+* ENUMS
+**********************************************************************************************************************/
+/***********************************************************************************************************************
+* DATA STRUCTURES
+***********************************************************************************************************************/
+/***********************************************************************************************************************
+* GLOBAL
+***********************************************************************************************************************/
+
+static host_lib_status_t pal_event_status;
+
+/***********************************************************************************************************************
+* LOCAL ROUTINES
+***********************************************************************************************************************/
+/// Physical Layer low level interface function
+static void ifx_i2c_pl_read_register(ifx_i2c_context_t *p_ctx,uint8_t reg_addr, uint16_t reg_len);
+/// Physical Layer low level interface function
+static void ifx_i2c_pl_write_register(ifx_i2c_context_t *p_ctx,uint8_t reg_addr, uint16_t reg_len, const uint8_t* p_content);
+/// Physical Layer high level interface timer callback (Status register polling)
+static void ifx_i2c_pl_status_poll_callback(void *p_ctx);
+/// Physical Layer intermediate state machine (Negotiation with slave)
+static void ifx_i2c_pl_negotiation_event_handler(void *p_input_ctx);
+/// Physical Layer intermediate state machine(Set bit rate)
+static host_lib_status_t ifx_i2c_pl_set_bit_rate(ifx_i2c_context_t *p_ctx, uint16_t bitrate);
+/// Physical Layer intermediate state machine (soft reset)
+static void ifx_i2c_pl_soft_reset(ifx_i2c_context_t *p_ctx);
+/// Physical Layer high level interface state machine (read/write frames)
+static void ifx_i2c_pl_frame_event_handler(ifx_i2c_context_t *p_ctx,host_lib_status_t event);
+/// Physical Layer low level interface timer callback (I2C Nack/Busy polling)
+static void ifx_i2c_pal_poll_callback(void *p_ctx);
+/// Physical Layer low level guard time callback
+static void ifx_i2c_pl_guard_time_callback(void *p_ctx);
+/// Physical Layer low level interface state machine (read/write registers)
+static void ifx_i2c_pl_pal_event_handler(void *p_ctx, host_lib_status_t event);
+/// Physical layer low level event handler for set slave address
+static void ifx_i2c_pl_pal_slave_addr_event_handler(void *p_input_ctx, host_lib_status_t event);
+
+/// @endcond
+/***********************************************************************************************************************
+* API PROTOTYPES
+**********************************************************************************************************************/
+/// Physical Layer high level interface function
+host_lib_status_t ifx_i2c_pl_init(ifx_i2c_context_t *p_ctx,ifx_i2c_event_handler_t handler)
+{
+ LOG_PL("[IFX-PL]: Init\n");
+
+ p_ctx->pl.upper_layer_event_handler = handler;
+ p_ctx->pl.frame_state = PL_STATE_UNINIT;
+ p_ctx->pl.negotiate_state = PL_INIT_SET_FREQ_DEFAULT;
+ p_ctx->p_pal_i2c_ctx->slave_address = p_ctx->slave_address;
+ p_ctx->p_pal_i2c_ctx->upper_layer_event_handler = (void *) ifx_i2c_pl_pal_event_handler;
+ p_ctx->pl.retry_counter = PL_POLLING_MAX_CNT;
+ if(TRUE == p_ctx->do_pal_init)
+ {
+ // Initialize I2C driver
+ if (PAL_STATUS_SUCCESS != pal_i2c_init(p_ctx->p_pal_i2c_ctx))
+ {
+ return IFX_I2C_STACK_ERROR;
+ }
+ }
+ // Set Physical Layer internal state
+ if(p_ctx->pl.request_soft_reset == (uint8_t)TRUE)
+ {
+ //Set the soft reset request to initial state to read register
+ p_ctx->pl.request_soft_reset = PL_INIT_GET_STATUS_REG;
+ p_ctx->pl.frame_state = PL_STATE_SOFT_RESET;
+ }
+ else
+ {
+ p_ctx->pl.frame_state = PL_STATE_INIT;
+ }
+
+ ifx_i2c_pl_frame_event_handler(p_ctx,IFX_I2C_STACK_SUCCESS);
+
+ return IFX_I2C_STACK_SUCCESS;
+}
+
+/// Physical Layer high level interface function
+host_lib_status_t ifx_i2c_pl_send_frame(ifx_i2c_context_t *p_ctx,uint8_t* p_frame, uint16_t frame_len)
+{
+ // Physical Layer must be idle, set requested action
+ if (p_ctx->pl.frame_state != PL_STATE_INIT && p_ctx->pl.frame_state != PL_STATE_READY)
+ {
+ return IFX_I2C_STACK_ERROR;
+ }
+ p_ctx->pl.frame_action = PL_ACTION_WRITE_FRAME;
+
+ // Store reference to frame for sending it later
+ p_ctx->pl.p_tx_frame = p_frame;
+ p_ctx->pl.tx_frame_len = frame_len;
+
+ ifx_i2c_pl_frame_event_handler(p_ctx,IFX_I2C_STACK_SUCCESS);
+ return IFX_I2C_STACK_SUCCESS;
+}
+
+/// Physical Layer high level interface function
+host_lib_status_t ifx_i2c_pl_receive_frame(ifx_i2c_context_t *p_ctx)
+{
+ // Physical Layer must be idle, set requested action
+ if (p_ctx->pl.frame_state != PL_STATE_INIT && p_ctx->pl.frame_state != PL_STATE_READY)
+ {
+ return IFX_I2C_STACK_ERROR;
+ }
+ p_ctx->pl.frame_action = PL_ACTION_READ_FRAME;
+
+ ifx_i2c_pl_frame_event_handler(p_ctx,IFX_I2C_STACK_SUCCESS);
+ return IFX_I2C_STACK_SUCCESS;
+}
+
+host_lib_status_t ifx_i2c_pl_write_slave_address(ifx_i2c_context_t *p_ctx, uint8_t slave_address, uint8_t persistent)
+{
+ host_lib_status_t status = IFX_I2C_STACK_ERROR;
+ app_event_handler_t * temp_upper_layer_event_handler;
+
+ /// @cond hidden
+ #define PAL_WRITE_INIT_STATUS (0x00FF)
+ #define ADDRESS_OFFSET (0x02)
+ #define BASE_ADDRESS_REG_OFFSET (0x00)
+ #define MODE_OFFSET (0x01)
+ #define POLLING_INTERVAL (0x01)
+ #define DELAY_FOR_COMPLETION (0x0A)
+ /// @endcond
+
+ //lint --e{611} suppress "void* function pointer is type casted to app_event_handler_t type"
+ //ifx i2c wrapper api for setting slave address in synchronous. hence the event handler is backed up.
+ temp_upper_layer_event_handler = (app_event_handler_t *)(p_ctx->p_pal_i2c_ctx->upper_layer_event_handler);
+ //since the lower level APIs are asynchronous, a temporary event handler for set slave address is assigned
+ p_ctx->p_pal_i2c_ctx->upper_layer_event_handler = (void *) ifx_i2c_pl_pal_slave_addr_event_handler;
+
+ p_ctx->pl.buffer[BASE_ADDRESS_REG_OFFSET] = PL_REG_BASE_ADDR;
+ p_ctx->pl.buffer[MODE_OFFSET] = PL_REG_BASE_ADDR_VOLATILE;
+ //supported base addresses are 0x00 - 0x7F. Hence 8th bit is ignored
+ p_ctx->pl.buffer[ADDRESS_OFFSET] = slave_address & PL_REG_I2C_BASE_ADDRESS_MASK;
+ p_ctx->pl.buffer_tx_len = 1 + PL_REG_LEN_BASE_ADDR;
+
+ if(PL_REG_BASE_ADDR_VOLATILE != persistent)
+ {
+ p_ctx->pl.buffer[MODE_OFFSET] = PL_REG_BASE_ADDR_PERSISTANT;
+ }
+
+ p_ctx->pl.retry_counter = PL_POLLING_MAX_CNT;
+
+ while(p_ctx->pl.retry_counter)
+ {
+ pal_event_status = PAL_WRITE_INIT_STATUS;
+
+ //lint --e{534} suppress "Return value is not required to be checked"
+ pal_i2c_write(p_ctx->p_pal_i2c_ctx,p_ctx->pl.buffer, p_ctx->pl.buffer_tx_len);
+ while(PAL_WRITE_INIT_STATUS == pal_event_status){};
+ if(PAL_I2C_EVENT_SUCCESS == pal_event_status)
+ {
+ break;
+ }
+ p_ctx->pl.retry_counter--;
+ pal_os_timer_delay_in_milliseconds(POLLING_INTERVAL);
+ }
+
+ if(PAL_I2C_EVENT_SUCCESS == pal_event_status)
+ {
+ p_ctx->p_pal_i2c_ctx->slave_address = p_ctx->pl.buffer[ADDRESS_OFFSET];
+ if(PL_REG_BASE_ADDR_VOLATILE != persistent)
+ {
+ p_ctx->slave_address = p_ctx->pl.buffer[ADDRESS_OFFSET];
+ }
+ pal_os_timer_delay_in_milliseconds(DELAY_FOR_COMPLETION);
+ status = IFX_I2C_STACK_SUCCESS;
+ }
+ //restoring the backed up event handler
+ p_ctx->p_pal_i2c_ctx->upper_layer_event_handler = temp_upper_layer_event_handler;
+
+ /// @cond hidden
+ #undef PAL_WRITE_INIT_STATUS
+ #undef ADDRESS_OFFSET
+ #undef BASE_ADDRESS_REG_OFFSET
+ #undef MODE_OFFSET
+ #undef POLLING_INTERVAL
+ #undef DELAY_FOR_COMPLETION
+ /// @endcond
+
+ return status;
+}
+
+static void ifx_i2c_pl_read_register(ifx_i2c_context_t *p_ctx,uint8_t reg_addr, uint16_t reg_len)
+{
+ LOG_PL("[IFX-PL]: Read register %x len %d\n", reg_addr, reg_len);
+
+ // Prepare transmit buffer to write register address
+ p_ctx->pl.buffer[0] = reg_addr;
+ p_ctx->pl.buffer_tx_len = 1;
+
+ // Set low level interface variables and start transmission
+ p_ctx->pl.buffer_rx_len = reg_len;
+ p_ctx->pl.register_action = PL_ACTION_READ_REGISTER;
+ p_ctx->pl.retry_counter = PL_POLLING_MAX_CNT;
+ p_ctx->pl.i2c_cmd = PL_I2C_CMD_WRITE;
+
+ //lint --e{534} suppress "Return value is not required to be checked"
+ pal_i2c_write(p_ctx->p_pal_i2c_ctx,p_ctx->pl.buffer, p_ctx->pl.buffer_tx_len);
+}
+
+
+static void ifx_i2c_pl_write_register(ifx_i2c_context_t *p_ctx,uint8_t reg_addr, uint16_t reg_len, const uint8_t* p_content)
+{
+ LOG_PL("[IFX-PL]: Write register %x len %d\n", reg_addr, reg_len);
+
+ // Prepare transmit buffer to write register address and content
+ p_ctx->pl.buffer[0] = reg_addr;
+ memcpy(p_ctx->pl.buffer + 1, p_content, reg_len);
+ p_ctx->pl.buffer_tx_len = 1 + reg_len;
+
+ // Set Physical Layer low level interface variables and start transmission
+ p_ctx->pl.register_action = PL_ACTION_WRITE_REGISTER;
+ p_ctx->pl.retry_counter = PL_POLLING_MAX_CNT;
+ p_ctx->pl.i2c_cmd = PL_I2C_CMD_WRITE;
+ //lint --e{534} suppress "Return value is not required to be checked"
+ pal_i2c_write(p_ctx->p_pal_i2c_ctx,p_ctx->pl.buffer, p_ctx->pl.buffer_tx_len);
+}
+
+
+static void ifx_i2c_pl_status_poll_callback(void *p_ctx)
+{
+ LOG_PL("[IFX-PL]: Status poll Timer elapsed -> Read STATUS register\n");
+ ifx_i2c_pl_read_register((ifx_i2c_context_t*)p_ctx,PL_REG_I2C_STATE, PL_REG_LEN_I2C_STATE);
+}
+
+static host_lib_status_t ifx_i2c_pl_set_bit_rate(ifx_i2c_context_t *p_ctx, uint16_t bitrate)
+{
+ host_lib_status_t status;
+ void* pal_ctx_upper_layer_handler;
+ // Save upper layer context in pal
+ pal_ctx_upper_layer_handler = p_ctx->p_pal_i2c_ctx->upper_layer_event_handler;
+ // Pass context as NULL to avoid callback invocation
+ p_ctx->p_pal_i2c_ctx->upper_layer_event_handler = NULL;
+ status = pal_i2c_set_bitrate(p_ctx->p_pal_i2c_ctx , bitrate);
+ // Restore callback
+ p_ctx->p_pal_i2c_ctx->upper_layer_event_handler = pal_ctx_upper_layer_handler;
+ if(PAL_I2C_EVENT_SUCCESS != status)
+ {
+ if (p_ctx->pl.retry_counter--)
+ {
+ LOG_PL("[IFX-PL]: Set bit rate failed, Retry setting.\n");
+ pal_os_event_register_callback_oneshot(ifx_i2c_pl_negotiation_event_handler,((void*)p_ctx),PL_POLLING_INVERVAL_US);
+ status = IFX_I2C_STACK_BUSY;
+ }
+ else
+ {
+ status = IFX_I2C_STACK_ERROR;
+ }
+ }
+ else
+ {
+ status = IFX_I2C_STACK_SUCCESS;
+ }
+
+ return status;
+
+}
+static void ifx_i2c_pl_negotiation_event_handler(void *p_input_ctx)
+{
+ host_lib_status_t event = (uint8_t)IFX_I2C_STACK_ERROR;
+ uint8_t continue_negotiation;
+ ifx_i2c_context_t* p_ctx = (ifx_i2c_context_t*)p_input_ctx;
+ uint8_t i2c_mode_value[2];
+ uint8_t max_frame_size[2] = { (uint8_t)(p_ctx->frame_size >> 8), (uint8_t)(p_ctx->frame_size) };
+ uint16_t buffer_len = 0;
+ uint16_t slave_frequency;
+ uint16_t slave_frame_len;
+ uint8_t* p_buffer = NULL;
+
+ do
+ {
+ continue_negotiation = FALSE;
+ LOG_PL("[IFX-PL]: Negotiation started\n");
+ switch(p_ctx->pl.negotiate_state)
+ {
+ // Set initial frequency to PL_DEFAULT_FREQUENCY to be able to negotiate with slave
+ case PL_INIT_SET_FREQ_DEFAULT:
+ {
+ // Default frequency set to master
+ event = ifx_i2c_pl_set_bit_rate(p_input_ctx,PL_DEFAULT_FREQUENCY);
+ if(IFX_I2C_STACK_SUCCESS == event)
+ {
+ p_ctx->pl.negotiate_state = PL_INIT_GET_FREQ_REG;
+ continue_negotiation = TRUE;
+ }
+ else if (IFX_I2C_STACK_ERROR == event)
+ {
+ p_ctx->pl.negotiate_state = PL_INIT_DONE;
+ p_buffer = NULL;
+ buffer_len = 0;
+ }
+ }
+ break;
+ // Read the current Max frequency supported by slave
+ case PL_INIT_GET_FREQ_REG:
+ {
+ p_ctx->pl.negotiate_state = PL_INIT_SET_FREQ_REG;
+ ifx_i2c_pl_read_register(p_ctx,PL_REG_MAX_SCL_FREQU, PL_REG_LEN_MAX_SCL_FREQU);
+ }
+ break;
+ // Set the I2C mode register
+ case PL_INIT_SET_FREQ_REG:
+ {
+ slave_frequency = (p_ctx->pl.buffer[2] << 8) | p_ctx->pl.buffer[3];
+
+ i2c_mode_value[0] = PL_REG_I2C_MODE_PERSISTANT;
+ if((p_ctx->frequency > PL_SM_FM_MAX_FREQUENCY)&&(slave_frequency<=PL_SM_FM_MAX_FREQUENCY))
+ {
+ //Change to FM+ mode if slave's current supported frequency is below user's requested frequency
+ i2c_mode_value[1] = PL_REG_I2C_MODE_FM_PLUS;
+ p_ctx->pl.negotiate_state = PL_INIT_READ_FREQ;
+ ifx_i2c_pl_write_register(p_ctx,PL_REG_I2C_MODE, PL_REG_LEN_I2C_MODE, i2c_mode_value);
+ }
+ else if((p_ctx->frequency <= PL_SM_FM_MAX_FREQUENCY)&&(slave_frequency>PL_SM_FM_MAX_FREQUENCY))
+ {
+ //Change to SM&FM mode if slave's current supported frequency is above user's requested frequency
+ i2c_mode_value[1] = PL_REG_I2C_MODE_SM_FM;
+ p_ctx->pl.negotiate_state = PL_INIT_READ_FREQ;
+ ifx_i2c_pl_write_register(p_ctx,PL_REG_I2C_MODE, PL_REG_LEN_I2C_MODE, i2c_mode_value);
+ }
+ else
+ {
+ p_ctx->pl.negotiate_state = PL_INIT_VERIFY_FREQ;
+ continue_negotiation = TRUE;
+ }
+ }
+ break;
+ // After setting I2C mode register, read the slave's supported frequency
+ case PL_INIT_READ_FREQ:
+ {
+ p_ctx->pl.negotiate_state = PL_INIT_VERIFY_FREQ;
+ ifx_i2c_pl_read_register(p_ctx,PL_REG_MAX_SCL_FREQU, PL_REG_LEN_MAX_SCL_FREQU);
+ }
+ break;
+ // Verify the requested frequency and slave's supported frequency
+ case PL_INIT_VERIFY_FREQ:
+ {
+ slave_frequency = (p_ctx->pl.buffer[2] << 8) | p_ctx->pl.buffer[3];
+ if(p_ctx->frequency > slave_frequency)
+ {
+ LOG_PL("[IFX-PL]: Unexpected frequency in MAX_SCL_FREQU\n");
+ p_buffer = NULL;
+ buffer_len = 0;
+ p_ctx->pl.negotiate_state = PL_INIT_DONE;
+ }
+ else
+ {
+ p_ctx->pl.negotiate_state = PL_INIT_AGREE_FREQ;
+ }
+ continue_negotiation = TRUE;
+ }
+ break;
+ // Frequency negotiated, Set frequency at master
+ case PL_INIT_AGREE_FREQ:
+ {
+ // Frequency negotiation between master and slave is complete
+ event = ifx_i2c_pl_set_bit_rate(p_input_ctx, p_ctx->frequency);
+ if(IFX_I2C_STACK_SUCCESS == event)
+ {
+ p_ctx->pl.negotiate_state = PL_INIT_SET_DATA_REG_LEN;
+ continue_negotiation = TRUE;
+ }
+ else if (IFX_I2C_STACK_ERROR == event)
+ {
+ p_ctx->pl.negotiate_state = PL_INIT_DONE;
+ p_buffer = NULL;
+ buffer_len = 0;
+ }
+ }
+ break;
+ // Start frame length negotiation by writing the requested frame length
+ case PL_INIT_SET_DATA_REG_LEN:
+ {
+ p_ctx->pl.negotiate_state = PL_INIT_GET_DATA_REG_LEN;
+ ifx_i2c_pl_write_register(p_ctx,PL_REG_DATA_REG_LEN, sizeof(max_frame_size), max_frame_size);
+ }
+ break;
+ // Read the frame length to verify
+ case PL_INIT_GET_DATA_REG_LEN:
+ {
+ p_ctx->pl.negotiate_state = PL_INIT_VERIFY_DATA_REG;
+ ifx_i2c_pl_read_register(p_ctx,PL_REG_DATA_REG_LEN,PL_REG_LEN_DATA_REG_LEN);
+ }
+ break;
+ // Check is slave accepted the new frame length
+ case PL_INIT_VERIFY_DATA_REG:
+ {
+ p_ctx->pl.negotiate_state = PL_INIT_DONE;
+ slave_frame_len = (p_ctx->pl.buffer[0] << 8) | p_ctx->pl.buffer[1];
+ // Error if slave's frame length is more than requested frame length
+ if(p_ctx->frame_size >= slave_frame_len)
+ {
+ p_ctx->frame_size = slave_frame_len;
+ event = IFX_I2C_STACK_SUCCESS;
+ }
+ p_buffer = NULL;
+ buffer_len = 0;
+ continue_negotiation = TRUE;
+ }
+ break;
+ case PL_INIT_DONE:
+ {
+ if(IFX_I2C_STACK_SUCCESS == event)
+ {
+ p_ctx->pl.frame_state = PL_STATE_READY;
+ }
+ else
+ {
+ p_ctx->pl.frame_state = PL_STATE_UNINIT;
+ }
+ // Negotiation between master and slave is complete
+ p_ctx->pl.upper_layer_event_handler(p_ctx,event, p_buffer, buffer_len);
+ }
+ break;
+ default:
+ break;
+ }
+ }while(continue_negotiation);
+}
+
+
+static void ifx_i2c_pl_frame_event_handler(ifx_i2c_context_t *p_ctx,host_lib_status_t event)
+{
+ uint16_t frame_size;
+ if (event != IFX_I2C_STACK_SUCCESS)
+ {
+ p_ctx->pl.frame_state = PL_STATE_READY;
+ // I2C read or write failed, report to upper layer
+ p_ctx->pl.upper_layer_event_handler(p_ctx,event, 0, 0);
+ }
+ else
+ {
+ switch(p_ctx->pl.frame_state)
+ {
+ // Perform soft reset
+ case PL_STATE_SOFT_RESET:
+ {
+ ifx_i2c_pl_soft_reset(p_ctx);
+ }
+ break;
+ // Negotiate frame and frequency with slave
+ case PL_STATE_INIT:
+ {
+ ifx_i2c_pl_negotiation_event_handler(p_ctx);
+ }
+ break;
+ // Check status of slave data
+ case PL_STATE_READY:
+ {
+ // Start polling status register
+ p_ctx->pl.frame_state = PL_STATE_DATA_AVAILABLE;
+ ifx_i2c_pl_read_register(p_ctx,PL_REG_I2C_STATE, PL_REG_LEN_I2C_STATE);
+ }
+ break;
+ // Do read/write frame
+ case PL_STATE_DATA_AVAILABLE:
+ {
+ // Read frame, if response is ready. Ignore busy flag
+ if ((p_ctx->pl.frame_action == PL_ACTION_READ_FRAME)
+ && (p_ctx->pl.buffer[0] & PL_REG_I2C_STATE_RESPONSE_READY))
+ {
+ frame_size = (p_ctx->pl.buffer[2] << 8) | p_ctx->pl.buffer[3];
+ if ((frame_size > 0) && (frame_size <= p_ctx->frame_size))
+ {
+ p_ctx->pl.frame_state = PL_STATE_RXTX;
+ ifx_i2c_pl_read_register(p_ctx,PL_REG_DATA, frame_size);
+ }
+ else
+ {
+ // Continue polling STATUS register if retry limit is not reached
+ if ((pal_os_timer_get_time_in_milliseconds() - p_ctx->dl.frame_start_time) < p_ctx->dl.data_poll_timeout)
+ {
+ pal_os_event_register_callback_oneshot(ifx_i2c_pl_status_poll_callback, (void *)p_ctx, PL_DATA_POLLING_INVERVAL_US);
+ }
+ else
+ {
+ p_ctx->pl.frame_state = PL_STATE_READY;
+ p_ctx->pl.upper_layer_event_handler(p_ctx,IFX_I2C_STACK_ERROR, 0, 0);
+ }
+ }
+ }
+ // Write frame is slave is not busy
+ else if (p_ctx->pl.frame_action == PL_ACTION_WRITE_FRAME)
+ {
+ // Write frame if device is not busy, otherwise wait and poll STATUS again later
+ p_ctx->pl.frame_state = PL_STATE_RXTX;
+ ifx_i2c_pl_write_register(p_ctx,PL_REG_DATA, p_ctx->pl.tx_frame_len, (uint8_t*)p_ctx->pl.p_tx_frame);
+ }
+ // Continue checking the slave status register
+ else
+ {
+ // Continue polling STATUS register if retry limit is not reached
+ if ((pal_os_timer_get_time_in_milliseconds() - p_ctx->dl.frame_start_time) < p_ctx->dl.data_poll_timeout)
+ {
+ pal_os_event_register_callback_oneshot(ifx_i2c_pl_status_poll_callback, (void *)p_ctx, PL_DATA_POLLING_INVERVAL_US);
+ }
+ else
+ {
+ p_ctx->pl.frame_state = PL_STATE_READY;
+ p_ctx->pl.upper_layer_event_handler(p_ctx,IFX_I2C_STACK_ERROR, 0, 0);
+ }
+ }
+ }
+ break;
+ // Frame reading is complete
+ case PL_STATE_RXTX:
+ {
+ // Writing/reading of frame to/from DATA register complete
+ p_ctx->pl.frame_state = PL_STATE_READY;
+ p_ctx->pl.upper_layer_event_handler(p_ctx,IFX_I2C_STACK_SUCCESS, p_ctx->pl.buffer, p_ctx->pl.buffer_rx_len);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+static void ifx_i2c_pal_poll_callback(void *p_ctx)
+{
+ ifx_i2c_context_t* p_local_ctx = (ifx_i2c_context_t *)p_ctx;
+ if (p_local_ctx->pl.i2c_cmd == PL_I2C_CMD_WRITE)
+ {
+ LOG_PL("[IFX-PL]: Poll Timer elapsed -> Restart TX\n");
+ //lint --e{534} suppress "Return value is not required to be checked"
+ pal_i2c_write(p_local_ctx->p_pal_i2c_ctx, p_local_ctx->pl.buffer, p_local_ctx->pl.buffer_tx_len);
+ }
+ else if (p_local_ctx->pl.i2c_cmd == PL_I2C_CMD_READ)
+ {
+ LOG_PL("[IFX-PL]: Poll Timer elapsed -> Restart Read Register -> Start TX\n");
+ //lint --e{534} suppress "Return value is not required to be checked"
+ pal_i2c_read(p_local_ctx->p_pal_i2c_ctx,p_local_ctx->pl.buffer, p_local_ctx->pl.buffer_rx_len);
+ }
+}
+
+
+static void ifx_i2c_pl_guard_time_callback(void *p_ctx)
+{
+ ifx_i2c_context_t* p_local_ctx = (ifx_i2c_context_t*)p_ctx;
+ if (p_local_ctx->pl.register_action == PL_ACTION_READ_REGISTER)
+ {
+ if (p_local_ctx->pl.i2c_cmd == PL_I2C_CMD_WRITE)
+ {
+ LOG_PL("[IFX-PL]: GT done-> Start RX\n");
+ p_local_ctx->pl.i2c_cmd = PL_I2C_CMD_READ;
+ //lint --e{534} suppress "Return value is not required to be checked"
+ pal_i2c_read(p_local_ctx->p_pal_i2c_ctx,p_local_ctx->pl.buffer, p_local_ctx->pl.buffer_rx_len);
+ }
+ else if (p_local_ctx->pl.i2c_cmd == PL_I2C_CMD_READ)
+ {
+ LOG_PL("[IFX-PL]: GT done -> REG is read\n");
+ ifx_i2c_pl_frame_event_handler(p_local_ctx,IFX_I2C_STACK_SUCCESS);
+ }
+ }
+ else if (p_local_ctx->pl.register_action == PL_ACTION_WRITE_REGISTER)
+ {
+ LOG_PL("[IFX-PL]: GT done -> REG written\n");
+ ifx_i2c_pl_frame_event_handler(p_local_ctx,IFX_I2C_STACK_SUCCESS);
+ }
+}
+
+static void ifx_i2c_pl_pal_event_handler(void *p_ctx, host_lib_status_t event)
+{
+ ifx_i2c_context_t* p_local_ctx = (ifx_i2c_context_t*)p_ctx;
+ switch (event)
+ {
+ case PAL_I2C_EVENT_ERROR:
+ case PAL_I2C_EVENT_BUSY:
+ // Error event usually occurs when the device is in sleep mode and needs time to wake up
+ if (p_local_ctx->pl.retry_counter--)
+ {
+ LOG_PL("[IFX-PL]: PAL Error -> Continue polling\n");
+ pal_os_event_register_callback_oneshot(ifx_i2c_pal_poll_callback,p_local_ctx,PL_POLLING_INVERVAL_US);
+ }
+ else
+ {
+ LOG_PL("[IFX-PL]: PAL Error -> Stop\n");
+ ifx_i2c_pl_frame_event_handler(p_local_ctx,IFX_I2C_FATAL_ERROR);
+ }
+ break;
+
+ case PAL_I2C_EVENT_SUCCESS:
+ LOG_PL("[IFX-PL]: PAL Success -> Wait Guard Time\n");
+ pal_os_event_register_callback_oneshot(ifx_i2c_pl_guard_time_callback,p_local_ctx,PL_GUARD_TIME_INTERVAL_US);
+ break;
+ default:
+ break;
+ }
+}
+
+
+static void ifx_i2c_pl_soft_reset(ifx_i2c_context_t *p_ctx)
+{
+ uint8_t i2c_mode_value[2] = {0};
+ switch(p_ctx->pl.request_soft_reset)
+ {
+ case PL_INIT_GET_STATUS_REG:
+ p_ctx->pl.request_soft_reset = PL_RESET_WRITE;
+ //Read the status register to check if soft reset is supported
+ ifx_i2c_pl_read_register(p_ctx, PL_REG_I2C_STATE, PL_REG_LEN_I2C_STATE);
+ break;
+
+ case PL_RESET_WRITE:
+ //Mask for soft reset bit(5th bit) from the 1st byte of status register
+ p_ctx->pl.buffer[0] &= PL_REG_I2C_STATE_SOFT_RESET;
+ if(p_ctx->pl.buffer[0] == PL_REG_I2C_STATE_SOFT_RESET)
+ {
+ p_ctx->pl.request_soft_reset = PL_RESET_STARTUP;
+ //Write 88 register with 0 value
+ ifx_i2c_pl_write_register(p_ctx, PL_REG_SOFT_RESET, PL_REG_LEN_SOFT_RESET, i2c_mode_value);
+ }
+ else
+ {
+ //Soft reset is not supported by the slave
+ p_ctx->pl.frame_state = PL_STATE_UNINIT;
+ ifx_i2c_pl_frame_event_handler(p_ctx, IFX_I2C_STACK_ERROR);
+ }
+ break;
+
+ case PL_RESET_STARTUP:
+ p_ctx->pl.request_soft_reset= PL_RESET_INIT;
+ pal_os_event_register_callback_oneshot((register_callback)ifx_i2c_pl_soft_reset, (void *)p_ctx, STARTUP_TIME_MSEC);
+ break;
+
+ case PL_RESET_INIT:
+ p_ctx->pl.frame_state = PL_STATE_INIT;
+ ifx_i2c_pl_frame_event_handler(p_ctx,IFX_I2C_STACK_SUCCESS);
+ break;
+
+ default:
+ break;
+ }
+}
+
+//lint --e{715} suppress "This is used for synchromous implementation, hence p_ctx not used"
+//lint --e{818} suppress "This is ignored as upper layer handler function prototype requires this argument"
+static void ifx_i2c_pl_pal_slave_addr_event_handler(void *p_ctx, host_lib_status_t event)
+{
+ pal_event_status = event;
+}
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/optiga_comms/ifx_i2c/ifx_i2c_transport_layer.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/optiga_comms/ifx_i2c/ifx_i2c_transport_layer.c
new file mode 100644
index 0000000..f3191e6
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/optiga_comms/ifx_i2c/ifx_i2c_transport_layer.c
@@ -0,0 +1,502 @@
+/**
+* \copyright
+* Copyright (c) 2018, Infineon Technologies AG
+* All rights reserved.
+*
+* This software is provided with terms and conditions as specified in OPTIGA(TM) Trust X Evaluation Kit License Agreement.
+* \endcopyright
+*
+* \author Infineon AG
+*
+* \file ifx_i2c_transport_layer.c
+*
+* \brief This file implements the IFX I2C Transport Layer.
+*
+* \addtogroup grIFXI2C
+* @{
+*/
+/***********************************************************************************************************************
+* HEADER FILES
+**********************************************************************************************************************/
+#include "ifx_i2c_transport_layer.h"
+#include "ifx_i2c_data_link_layer.h" // include lower layer header
+
+/// @cond hidden
+/***********************************************************************************************************************
+* MACROS
+**********************************************************************************************************************/
+// Transport Layer states
+#define TL_STATE_UNINIT (0x00)
+#define TL_STATE_IDLE (0x01)
+#define TL_STATE_TX (0x02)
+#define TL_STATE_RX (0x04)
+#define TL_STATE_CHAINING (0x05)
+#define TL_STATE_ERROR (0x06)
+#define TL_STATE_CHAINING_ERROR (0x07)
+#define TL_STATE_RESEND (0x08)
+// Transport Layer header size
+#define TL_HEADER_SIZE 1
+
+// Transport Layer chaining values
+#define TL_CHAINING_NO (0x00)
+#define TL_CHAINING_FIRST (0x01)
+#define TL_CHAINING_INTERMEDIATE (0x02)
+#define TL_CHAINING_LAST (0x04)
+#define TL_CHAINING_ERROR (0x07)
+
+#define TL_PCTR_CHANNEL_MASK (0xF8)
+#define TL_PCTR_CHAIN_MASK (0x07)
+// Setup debug log statements
+#if IFX_I2C_LOG_TL == 1
+#define LOG_TL IFX_I2C_LOG
+#else
+#define LOG_TL(...) //printf(__VA_ARGS__);
+#endif
+/***********************************************************************************************************************
+* ENUMS
+**********************************************************************************************************************/
+/***********************************************************************************************************************
+* DATA STRUCTURES
+***********************************************************************************************************************/
+static uint8_t pctr_states_table[5][2]={
+ {TL_CHAINING_NO,TL_CHAINING_LAST},
+ {TL_CHAINING_NO,TL_CHAINING_LAST},
+ {TL_CHAINING_FIRST,TL_CHAINING_INTERMEDIATE},
+ {0xFF,0xFF},
+ {TL_CHAINING_FIRST,TL_CHAINING_INTERMEDIATE},
+ };
+/***********************************************************************************************************************
+* GLOBAL
+***********************************************************************************************************************/
+
+/***********************************************************************************************************************
+* LOCAL ROUTINES
+***********************************************************************************************************************/
+/// Sends available fragment
+_STATIC_H host_lib_status_t ifx_i2c_tl_send_next_fragment(ifx_i2c_context_t *p_ctx);
+/// Datalink Layer event handler
+_STATIC_H void ifx_i2c_dl_event_handler(ifx_i2c_context_t* p_ctx,host_lib_status_t event, const uint8_t* p_data, uint16_t data_len);
+/// Resends all the packets
+_STATIC_H host_lib_status_t ifx_i2c_tl_resend_packets(ifx_i2c_context_t *p_ctx);
+/// Sends chaining error to I2C slave
+_STATIC_H host_lib_status_t ifx_i2c_tl_send_chaining_error(ifx_i2c_context_t *p_ctx);
+/// Calculates the pctr value
+_STATIC_H uint8_t ifx_i2c_tl_calculate_pctr(const ifx_i2c_context_t *p_ctx);
+/// Checks if chaining error occured based on current and previous pctr
+_STATIC_H host_lib_status_t ifx_i2c_tl_check_chaining_error(uint8_t current_chaning, uint8_t previous_chaining);
+/// @endcond
+/***********************************************************************************************************************
+* API PROTOTYPES
+**********************************************************************************************************************/
+/// Transport Layer initialization function
+host_lib_status_t ifx_i2c_tl_init(ifx_i2c_context_t *p_ctx,ifx_i2c_event_handler_t handler)
+{
+ LOG_TL("[IFX-TL]: Init\n");
+
+ p_ctx->tl.state = TL_STATE_UNINIT;
+
+ // Initialize Data Link layer (and register event handler)
+ if (ifx_i2c_dl_init(p_ctx,ifx_i2c_dl_event_handler) != IFX_I2C_STACK_SUCCESS)
+ {
+ return IFX_I2C_STACK_ERROR;
+ }
+
+ p_ctx->tl.upper_layer_event_handler = handler;
+ p_ctx->tl.state = TL_STATE_IDLE;
+ p_ctx->tl.max_packet_length = p_ctx->frame_size - (DL_HEADER_SIZE + TL_HEADER_SIZE);
+
+ return IFX_I2C_STACK_SUCCESS;
+}
+
+
+host_lib_status_t ifx_i2c_tl_transceive(ifx_i2c_context_t *p_ctx,uint8_t* p_packet, uint16_t packet_len,
+ uint8_t* p_recv_packet, uint16_t* recv_packet_len)
+{
+ host_lib_status_t status = IFX_I2C_STACK_ERROR;
+ LOG_TL("[IFX-TL]: Transceive txlen %d\n", packet_len);
+
+ do
+ {
+ // Check function arguments
+ if (p_packet == NULL || packet_len == 0 )
+ {
+ break;
+ }
+ // Transport Layer must be idle
+ if (p_ctx->tl.state != TL_STATE_IDLE)
+ {
+ break;
+ }
+ p_ctx->tl.state = TL_STATE_TX;
+ p_ctx->tl.api_start_time = pal_os_timer_get_time_in_milliseconds();
+ p_ctx->tl.p_actual_packet = p_packet;
+ p_ctx->tl.actual_packet_length = packet_len;
+ p_ctx->tl.packet_offset = 0;
+ p_ctx->tl.p_recv_packet_buffer = p_recv_packet;
+ p_ctx->tl.p_recv_packet_buffer_length = recv_packet_len;
+ p_ctx->tl.total_recv_length = 0;
+ p_ctx->tl.chaining_error_count = 0;
+ p_ctx->tl.master_chaining_error_count = 0;
+ p_ctx->tl.transmission_completed = 0;
+ p_ctx->tl.error_event = IFX_I2C_STACK_ERROR;
+ status = ifx_i2c_tl_send_next_fragment(p_ctx);
+ }while(FALSE);
+ return status;
+}
+
+
+_STATIC_H host_lib_status_t ifx_i2c_tl_resend_packets(ifx_i2c_context_t *p_ctx)
+{
+ // Transport Layer must be idle
+ if (p_ctx->tl.state != TL_STATE_IDLE)
+ {
+ return IFX_I2C_STACK_ERROR;
+ }
+
+ p_ctx->tl.packet_offset = 0;
+ p_ctx->tl.total_recv_length = 0;
+ p_ctx->tl.state = TL_STATE_TX;
+ return ifx_i2c_tl_send_next_fragment(p_ctx);
+}
+
+_STATIC_H uint8_t ifx_i2c_tl_calculate_pctr(const ifx_i2c_context_t *p_ctx)
+{
+ uint8_t pctr;
+ uint16_t fragment_size = p_ctx->tl.max_packet_length;
+ uint16_t remaining_data = p_ctx->tl.actual_packet_length - p_ctx->tl.packet_offset;
+ // No chain
+ if((p_ctx->tl.packet_offset==0)&&(remaining_data<=fragment_size))
+ {
+ pctr = TL_CHAINING_NO;
+ }
+ // First chain
+ else if((p_ctx->tl.packet_offset==0)&&(remaining_data>fragment_size))
+ {
+ pctr = TL_CHAINING_FIRST;
+ }
+ // Intermediate chain
+ else if((p_ctx->tl.packet_offset!=0)&&(remaining_data>fragment_size))
+ {
+ pctr = TL_CHAINING_INTERMEDIATE;
+ }
+ // Last chain
+ else
+ {
+ pctr = TL_CHAINING_LAST;
+ }
+
+ return pctr;
+}
+_STATIC_H host_lib_status_t ifx_i2c_tl_send_next_fragment(ifx_i2c_context_t *p_ctx)
+{
+ uint8_t pctr = 0;
+ // Calculate size of fragment (last one might be shorter)
+ uint16_t tl_fragment_size = p_ctx->tl.max_packet_length;
+ pctr = ifx_i2c_tl_calculate_pctr(p_ctx);
+ if ((p_ctx->tl.actual_packet_length - p_ctx->tl.packet_offset) < tl_fragment_size)
+ {
+ tl_fragment_size = p_ctx->tl.actual_packet_length - p_ctx->tl.packet_offset;
+ }
+
+ // Assign the pctr
+ p_ctx->tx_frame_buffer[IFX_I2C_TL_HEADER_OFFSET] = pctr;
+ //copy the data
+ memcpy(p_ctx->tx_frame_buffer+IFX_I2C_TL_HEADER_OFFSET+1,p_ctx->tl.p_actual_packet + p_ctx->tl.packet_offset,tl_fragment_size);
+ p_ctx->tl.packet_offset += tl_fragment_size;
+ //send the fragment to dl layer
+ return ifx_i2c_dl_send_frame(p_ctx,tl_fragment_size+1);
+}
+
+_STATIC_H host_lib_status_t ifx_i2c_tl_send_chaining_error(ifx_i2c_context_t *p_ctx)
+{
+ uint16_t tl_fragment_size = 1;
+ p_ctx->tx_frame_buffer[IFX_I2C_TL_HEADER_OFFSET] = 0x07;
+ p_ctx->tl.total_recv_length = 0;
+ //send the fragment to dl layer
+ return ifx_i2c_dl_send_frame(p_ctx,tl_fragment_size);
+}
+
+_STATIC_H host_lib_status_t ifx_i2c_tl_check_chaining_error(uint8_t current_chaning, uint8_t previous_chaining)
+{
+ host_lib_status_t status = IFX_I2C_STACK_ERROR;
+ if(((current_chaning == TL_CHAINING_ERROR) || (current_chaning == TL_CHAINING_NO) || (current_chaning == TL_CHAINING_LAST)
+ || (current_chaning == TL_CHAINING_INTERMEDIATE) || (current_chaning == TL_CHAINING_FIRST)))
+ {
+ if((pctr_states_table[current_chaning][0] == previous_chaining) || (pctr_states_table[current_chaning][1] == previous_chaining))
+ {
+ status = IFX_I2C_STACK_SUCCESS;
+ }
+ }
+
+ return status;
+}
+
+_STATIC_H void ifx_i2c_dl_event_handler(ifx_i2c_context_t* p_ctx,host_lib_status_t event, const uint8_t* p_data, uint16_t data_len)
+{
+ uint8_t pctr = 0;
+ uint8_t chaining = 0;
+ uint8_t exit_machine = TRUE;
+ do
+ {
+ if(NULL != p_data)
+ {
+ pctr = p_data[0];
+ chaining = pctr & TL_PCTR_CHAIN_MASK;
+ }
+ // Propagate errors to upper layer
+ if ((event & IFX_I2C_DL_EVENT_ERROR)||(pctr & TL_PCTR_CHANNEL_MASK))
+ {
+ p_ctx->tl.state = TL_STATE_ERROR;
+ p_ctx->tl.error_event = IFX_I2C_STACK_ERROR;
+ }
+ switch(p_ctx->tl.state)
+ {
+ case TL_STATE_IDLE:
+ {
+ exit_machine = FALSE;
+ p_ctx->tl.upper_layer_event_handler(p_ctx,IFX_I2C_STACK_SUCCESS, 0, 0);
+ }
+ break;
+ case TL_STATE_TX:
+ {
+ // Frame transmission in Data Link layer complete, start receiving frames
+ if (event & IFX_I2C_DL_EVENT_TX_SUCCESS)
+ {
+ if (p_ctx->tl.packet_offset < p_ctx->tl.actual_packet_length)
+ {
+ // Transmission of one fragment complete, send next fragment
+ LOG_TL("[IFX-TL]: Tx:Fragment sent,now send next\n");
+ // Chaining error from slave
+ if(TL_CHAINING_ERROR == chaining)
+ {
+ LOG_TL("[IFX-TL]: Tx:Chaining error received while Tx\n");
+ p_ctx->tl.state = TL_STATE_RESEND;
+ break;
+ }
+ // Any fragment received before complete transmission is error
+ if(data_len)
+ {
+ LOG_TL("[IFX-TL]: Tx:Data received while Tx\n");
+ p_ctx->tl.state = TL_STATE_ERROR;
+ break;
+ }
+ exit_machine = FALSE;
+ //lint --e{534} suppress "Return value is not required to be checked"
+ ifx_i2c_tl_send_next_fragment(p_ctx);
+ }
+ else
+ {
+ // Transmission of all fragments complete, start receiving fragments
+ LOG_TL("[IFX-TL]: Tx:All fragment sent\n");
+ p_ctx->tl.state = TL_STATE_RX;
+ p_ctx->tl.total_recv_length = 0;
+ p_ctx->tl.previous_chaining = TL_CHAINING_NO;
+ p_ctx->tl.transmission_completed = 1;
+ // if data is received after sending last frame
+ if (!(event & IFX_I2C_DL_EVENT_RX_SUCCESS))
+ {
+ LOG_TL("[IFX-TL]: Tx:Data already received after Tx\n");
+ // Received CTRL frame, trigger reception in Data Link layer
+ if (ifx_i2c_dl_receive_frame(p_ctx))
+ {
+ LOG_TL("[IFX-TL]: Tx:RX Received CTRL frame fail -> Inform UL\n");
+ p_ctx->tl.state = TL_STATE_ERROR;
+ }
+ exit_machine = FALSE;
+ }
+ }
+ }
+ else
+ {
+ LOG_TL("[IFX-TL]: Tx:IFX_I2C_DL_EVENT_TX_SUCCESS is not satisfied Tx\n");
+ p_ctx->tl.state = TL_STATE_ERROR;
+ break;
+ }
+ }
+ break;
+ case TL_STATE_RX:
+ {
+ // Reception of frame from Data Link layer
+ if (event & IFX_I2C_DL_EVENT_RX_SUCCESS)
+ {
+ // Message must contain at least the transport layer header
+ if (data_len < TL_HEADER_SIZE)
+ {
+ LOG_TL("[IFX-TL]: Rx : Data received is more than header len\n");
+ p_ctx->tl.state = TL_STATE_ERROR;
+ break;
+ }
+
+ if(p_ctx->tl.error_event == IFX_I2C_STACK_MEM_ERROR)
+ {
+ if ((chaining == TL_CHAINING_LAST) || (ifx_i2c_dl_receive_frame(p_ctx)))
+ {
+ p_ctx->tl.state = TL_STATE_ERROR;
+ break;
+ }
+ p_ctx->tl.state = TL_STATE_RX;
+ exit_machine = FALSE;
+ break;
+ }
+
+ // If chaining error detected
+ if(IFX_I2C_STACK_SUCCESS != ifx_i2c_tl_check_chaining_error(chaining,p_ctx->tl.previous_chaining))
+ {
+ LOG_TL("[IFX-TL]: Rx : Chaining state is not correct\n");
+ p_ctx->tl.state = TL_STATE_RESEND;
+ break;
+ }
+
+ p_ctx->tl.previous_chaining = chaining;
+ if(NULL == p_data)
+ {
+ p_ctx->tl.state = TL_STATE_ERROR;
+ break;
+ }
+
+ // No chaining and Last
+ if ((chaining == TL_CHAINING_NO)||(chaining == TL_CHAINING_LAST))
+ {
+ LOG_TL("[IFX-TL]: Rx : No chain/Last chain received, Inform UL\n");
+
+ exit_machine = FALSE;
+ // Copy frame payload to transport layer receive buffer
+ memcpy(p_ctx->tl.p_recv_packet_buffer + p_ctx->tl.total_recv_length, p_data + 1, data_len - 1);
+ p_ctx->tl.total_recv_length += (data_len - 1);
+ // Inform upper layer that a packet has arrived
+ p_ctx->tl.state = TL_STATE_IDLE;
+ *p_ctx->tl.p_recv_packet_buffer_length = p_ctx->tl.total_recv_length;
+ p_ctx->tl.upper_layer_event_handler(p_ctx,IFX_I2C_STACK_SUCCESS, p_ctx->tl.p_recv_packet_buffer, *p_ctx->tl.p_recv_packet_buffer_length);
+ }
+ else
+ {
+ p_ctx->tl.state = TL_STATE_CHAINING;
+ }
+ }
+ else
+ {
+ LOG_TL("[IFX-TL]: Tx:IFX_I2C_DL_EVENT_TX_SUCCESS is not satisfied Tx\n");
+ p_ctx->tl.state = TL_STATE_ERROR;
+ break;
+ }
+ }
+ break;
+
+ case TL_STATE_CHAINING:
+ {
+ LOG_TL("[IFX-TL]: Chain : Chaining mode entered\n");
+ // When receiving a starting fragment, fragment length must be max frame size for intermediate and last frame
+ // the buffer should not be empty
+ if (data_len != (p_ctx->tl.max_packet_length+1))
+ {
+ LOG_TL("[IFX-TL]: Chain : Data len not equal to max frame size\n");
+ p_ctx->tl.state = TL_STATE_CHAINING_ERROR;
+ break;
+ }
+ // Check for possible receive buffer overflow
+ if ((p_ctx->tl.total_recv_length + data_len - 1) > (*p_ctx->tl.p_recv_packet_buffer_length))
+ {
+ LOG_TL("[IFX-TL]: Chain : Buffer overflow\n");
+ p_ctx->tl.error_event = IFX_I2C_STACK_MEM_ERROR;
+ p_ctx->tl.state = TL_STATE_RX;
+ break;
+ }
+ if(NULL == p_data)
+ {
+ p_ctx->tl.state = TL_STATE_ERROR;
+ break;
+ }
+ // Copy frame payload to transport layer receive buffer
+ memcpy(p_ctx->tl.p_recv_packet_buffer + p_ctx->tl.total_recv_length, p_data + 1, data_len - 1);
+ p_ctx->tl.total_recv_length += (data_len - 1);
+
+ p_ctx->tl.previous_chaining = pctr;
+ LOG_TL("[IFX-TL]: Chain : Continue in receive mode\n");
+ p_ctx->tl.state = TL_STATE_RX;
+ // Continue receiving frames until packet is complete
+ if (ifx_i2c_dl_receive_frame(p_ctx))
+ {
+ p_ctx->tl.state = TL_STATE_ERROR;
+ }
+ exit_machine = FALSE;
+ }
+ break;
+
+ case TL_STATE_RESEND:
+ {
+ LOG_TL("[IFX-TL]: Resend Enter\n");
+ // In received mode , for wrong pctr with data
+ if((data_len > 1) && (p_ctx->tl.transmission_completed == 1))
+ {
+ LOG_TL("[IFX-TL]: Resend : Send chaining error\n");
+ p_ctx->tl.state = TL_STATE_CHAINING_ERROR;
+ break;
+ }
+ // Master Resend the packets,Resend only once, otherwise exit with error
+ if(0 == (p_ctx->tl.chaining_error_count++))
+ {
+ LOG_TL("[IFX-TL]: Resend : Resending\n");
+ p_ctx->tl.state = TL_STATE_IDLE;
+ if(ifx_i2c_tl_resend_packets(p_ctx))
+ {
+ p_ctx->tl.state = TL_STATE_ERROR;
+ }
+ else
+ {
+ exit_machine = FALSE;
+ }
+ }
+ else
+ {
+ LOG_TL("[IFX-TL]: Resend : chaining_error_count exceeded\n");
+ p_ctx->tl.state = TL_STATE_ERROR;
+ }
+ }
+ break;
+
+ case TL_STATE_CHAINING_ERROR:
+ {
+ // Send chaining error to slave
+ p_ctx->tl.state = TL_STATE_TX;
+ if(0 == (p_ctx->tl.master_chaining_error_count++))
+ {
+ LOG_TL("[IFX-TL]: Chain error : Sending chain error\n");
+ // Send chaining error only once
+ if(ifx_i2c_tl_send_chaining_error(p_ctx))
+ {
+ p_ctx->tl.state = TL_STATE_ERROR;
+ }
+ else
+ {
+ exit_machine = FALSE;
+ }
+ }
+ else
+ {
+ LOG_TL("[IFX-TL]: Chain error : master_chaining_error_count exceeded\n");
+ p_ctx->tl.state = TL_STATE_ERROR;
+ }
+ }
+ break;
+ case TL_STATE_ERROR:
+ {
+ LOG_TL("[IFX-TL]: Error\n");
+ exit_machine = FALSE;
+ if ((event & IFX_I2C_DL_EVENT_ERROR) || (data_len))
+ {
+ p_ctx->tl.state = TL_STATE_IDLE;
+ }
+ p_ctx->tl.upper_layer_event_handler(p_ctx,p_ctx->tl.error_event, 0u, 0u);
+ }
+ break;
+ default:
+ LOG_TL("[IFX-TL]: Exit from default case\n");
+ p_ctx->tl.state = TL_STATE_IDLE;
+ exit_machine = FALSE;
+ p_ctx->tl.upper_layer_event_handler(p_ctx,p_ctx->tl.error_event, 0u, 0u);
+ break;
+ }
+ }while(exit_machine);
+}
+
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/optiga_comms/optiga_comms_ifx_i2c.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/optiga_comms/optiga_comms_ifx_i2c.c
new file mode 100644
index 0000000..92db5d2
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/optiga_comms/optiga_comms_ifx_i2c.c
@@ -0,0 +1,250 @@
+/**
+* \copyright
+* Copyright (c) 2018, Infineon Technologies AG
+* All rights reserved.
+*
+* This software is provided with terms and conditions as specified in OPTIGA(TM) Trust X Evaluation Kit License Agreement.
+* \endcopyright
+*
+* \author Infineon AG
+*
+* \file
+*
+* \brief This file implements optiga comms abstraction layer for IFX I2C Protocol.
+*
+* \addtogroup grOptigaComms
+* @{
+*/
+
+/**********************************************************************************************************************
+ * HEADER FILES
+ *********************************************************************************************************************/
+#include "optiga_comms.h"
+#include "ifx_i2c.h"
+/// @cond hidden
+/**********************************************************************************************************************
+ * MACROS
+ *********************************************************************************************************************/
+ /// Optiga comms is in use
+ #define OPTIGA_COMMS_INUSE (0x01)
+ /// Optiga comms is free
+ #define OPTIGA_COMMS_FREE (0x00)
+/**********************************************************************************************************************
+ * LOCAL DATA
+ *********************************************************************************************************************/
+/**********************************************************************************************************************
+ * LOCAL ROUTINES
+ *********************************************************************************************************************/
+static host_lib_status_t check_optiga_comms_state(optiga_comms_t *p_ctx);
+static void ifx_i2c_event_handler(void* upper_layer_ctx, host_lib_status_t event);
+
+/// @endcond
+/**********************************************************************************************************************
+ * API IMPLEMENTATION
+ *********************************************************************************************************************/
+
+/**
+ * Initializes the commmunication with OPTIGA.<br>
+ *
+ *<b>Pre Conditions:</b>
+ * - None<br>
+ *
+ *<b>API Details:</b>
+ * - Initializes OPTIGA and establishes the communication channel.<br>
+ * - Initializes the ifx i2c protocol stack and registers the event callbacks.<br>
+ * - Negotiates the frame size and bit rate with the OPTIGA.<br>
+ *<br>
+ *
+ *<b>User Input:</b><br>
+ * - The input #optiga_comms_t p_ctx must not be NULL.<br>
+ * - The following parameters in #optiga_comms_t must be initialized with appropriate values.<br>
+ * - The <b>comms_ctx</b> must be initialized with a valid #ifx_i2c_context.<br>
+ * - The <b>upper_layer_event_handler</b> parameter must be properly initialized.
+ * This is invoked when #optiga_comms_open is asynchronously completed.<br>
+ * - The <b>upper_layer_ctx</b> must be properly initialized.<br>
+ *
+ *<b>Notes:</b>
+ * - None<br>
+ *
+ *<br>
+ * \param[in,out] p_ctx Pointer to optiga comms context
+ *
+ * \retval #OPTIGA_COMMS_SUCCESS
+ * \retval #OPTIGA_COMMS_ERROR
+ */
+host_lib_status_t optiga_comms_open(optiga_comms_t *p_ctx)
+{
+ host_lib_status_t status = OPTIGA_COMMS_ERROR;
+ if (OPTIGA_COMMS_SUCCESS == check_optiga_comms_state(p_ctx))
+ {
+ ((ifx_i2c_context_t*)(p_ctx->comms_ctx))->p_upper_layer_ctx = (void*)p_ctx;
+ ((ifx_i2c_context_t*)(p_ctx->comms_ctx))->upper_layer_event_handler = ifx_i2c_event_handler;
+ status = ifx_i2c_open((ifx_i2c_context_t*)(p_ctx->comms_ctx));
+ if (IFX_I2C_STACK_SUCCESS != status)
+ {
+ p_ctx->state = OPTIGA_COMMS_FREE;
+ }
+ }
+ return status;
+}
+
+/**
+ * Resets the OPTIGA.<br>
+ *
+ *<b>Pre Conditions:</b>
+ * - Communication channel must be established with OPTIGA.<br>
+ *
+ *<b>API Details:</b>
+ * - Resets the OPTIGA device.<br>
+ * - Initializes the ifx i2c protocol stack.<br>
+ * - Re-Initializes and negotiates the frame size and bit rate with the OPTIGA.
+ * The values remain same as that in previous #optiga_comms_open().<br>
+ *<br>
+ *
+ *<b>User Input:</b><br>
+ * - The input #optiga_comms_t p_ctx must not be NULL.
+ *
+ *<b>Notes:</b>
+ * For COLD and WARM reset type: If the gpio(vdd and/or reset) pins are not configured,
+ * the API continues without returning error status<br>
+ *
+ *
+ * \param[in,out] p_ctx Pointer to #optiga_comms_t
+ * \param[in,out] reset_type type of reset
+ *
+ * \retval #OPTIGA_COMMS_SUCCESS
+ * \retval #OPTIGA_COMMS_ERROR
+ */
+host_lib_status_t optiga_comms_reset(optiga_comms_t *p_ctx,uint8_t reset_type)
+{
+ host_lib_status_t status = OPTIGA_COMMS_ERROR;
+ if (OPTIGA_COMMS_SUCCESS == check_optiga_comms_state(p_ctx))
+ {
+ ((ifx_i2c_context_t*)(p_ctx->comms_ctx))->p_upper_layer_ctx = (void*)p_ctx;
+ ((ifx_i2c_context_t*)(p_ctx->comms_ctx))->upper_layer_event_handler = ifx_i2c_event_handler;
+ status = ifx_i2c_reset((ifx_i2c_context_t*)(p_ctx->comms_ctx),(ifx_i2c_reset_type_t)reset_type);
+ if (IFX_I2C_STACK_SUCCESS != status)
+ {
+ p_ctx->state = OPTIGA_COMMS_FREE;
+ }
+ }
+ return status;
+}
+
+/**
+ * Sends a command to OPTIGA and receives a response.<br>
+ *
+ *
+ *<b>Pre Conditions:</b>
+ * - Communication channel must be established with OPTIGA.<br>
+ *
+ *<b>API Details:</b>
+ * - Transmit data(Command) to OPTIGA.<br>
+ * - Receive data(Response) from OPTIGA.<br>
+ *<br>
+ *
+ *<b>User Input:</b><br>
+ * - The input #optiga_comms_t p_ctx must not be NULL.<br>
+ * - The following parameters in #optiga_comms_t must be initialized with appropriate values <br>
+ * - The <b>comms_ctx</b> must be initialized with a valid #ifx_i2c_context<br>
+ * - The <b>upper_layer_event_handler</b> parameter must be properly initialized,
+ * if it is different from that in #optiga_comms_open().
+ * This is invoked when optiga_comms_transceive is asynchronously completed.<br>
+ * - The <b>upper_layer_ctx</b> must be properly initialized,
+ * if it is different from that in #optiga_comms_open().<br>
+ *
+ *<b>Notes:</b>
+ * - The actual number of bytes received is stored in p_buffer_len. In case of error, p_buffer_len is set to 0.<br>
+ * - If the size of p_buffer is zero or insufficient to copy the response bytes then
+ * #IFX_I2C_STACK_MEM_ERROR error is returned.
+ *
+ *
+ * \param[in,out] p_ctx Pointer to #optiga_comms_t
+ * \param[in] p_data Pointer to the write data buffer
+ * \param[in] p_data_length Pointer to the length of the write data buffer
+ * \param[in,out] p_buffer Pointer to the receive data buffer
+ * \param[in,out] p_buffer_len Pointer to the length of the receive data buffer
+ *
+ * \retval #OPTIGA_COMMS_SUCCESS
+ * \retval #OPTIGA_COMMS_ERROR
+ * \retval #IFX_I2C_STACK_MEM_ERROR
+ */
+host_lib_status_t optiga_comms_transceive(optiga_comms_t *p_ctx,const uint8_t* p_data,
+ const uint16_t* p_data_length,
+ uint8_t* p_buffer, uint16_t* p_buffer_len)
+{
+ host_lib_status_t status = OPTIGA_COMMS_ERROR;
+ if (OPTIGA_COMMS_SUCCESS == check_optiga_comms_state(p_ctx))
+ {
+ ((ifx_i2c_context_t*)(p_ctx->comms_ctx))->p_upper_layer_ctx = (void*)p_ctx;
+ ((ifx_i2c_context_t*)(p_ctx->comms_ctx))->upper_layer_event_handler = ifx_i2c_event_handler;
+ status = (ifx_i2c_transceive((ifx_i2c_context_t*)(p_ctx->comms_ctx),p_data,p_data_length,p_buffer,p_buffer_len));
+ if (IFX_I2C_STACK_SUCCESS != status)
+ {
+ p_ctx->state = OPTIGA_COMMS_FREE;
+ }
+ }
+ return status;
+}
+
+/**
+ * Closes the communication with OPTIGA.<br>
+ *
+ *<b>Pre Conditions:</b>
+ * - None<br>
+ *
+ *<b>API Details:</b>
+ * - De-Initializes the OPTIGA and closes the communication channel.<br>
+ * - Power downs the OPTIGA.<br>
+ *<br>
+ *
+ *<b>User Input:</b><br>
+ * - The input #optiga_comms_t p_ctx must not be NULL.<br>
+ * - The #optiga_comms_t comms_ctx must be initialized with a valid #ifx_i2c_context<br>
+ *
+ * \param[in,out] p_ctx Pointer to #optiga_comms_t
+ *
+ * \retval #OPTIGA_COMMS_SUCCESS
+ * \retval #OPTIGA_COMMS_ERROR
+ */
+host_lib_status_t optiga_comms_close(optiga_comms_t *p_ctx)
+{
+ host_lib_status_t status = OPTIGA_COMMS_ERROR;
+ if (OPTIGA_COMMS_SUCCESS == check_optiga_comms_state(p_ctx))
+ {
+ ((ifx_i2c_context_t*)(p_ctx->comms_ctx))->p_upper_layer_ctx = (void*)p_ctx;
+ ((ifx_i2c_context_t*)(p_ctx->comms_ctx))->upper_layer_event_handler = ifx_i2c_event_handler;
+ status = ifx_i2c_close((ifx_i2c_context_t*)(p_ctx->comms_ctx));
+ if (IFX_I2C_STACK_SUCCESS != status)
+ {
+ p_ctx->state = OPTIGA_COMMS_FREE;
+ }
+ }
+ return status;
+}
+
+/// @cond hidden
+static host_lib_status_t check_optiga_comms_state(optiga_comms_t *p_ctx)
+{
+ host_lib_status_t status = OPTIGA_COMMS_ERROR;
+ if ((NULL != p_ctx) && (p_ctx->state != OPTIGA_COMMS_INUSE))
+ {
+ p_ctx->state = OPTIGA_COMMS_INUSE;
+ status = OPTIGA_COMMS_SUCCESS;
+ }
+ return status;
+}
+
+//lint --e{818} suppress "This is ignored as upper layer handler function prototype requires this argument"
+static void ifx_i2c_event_handler(void* upper_layer_ctx, host_lib_status_t event)
+{
+ void* ctx = ((optiga_comms_t*)upper_layer_ctx)->upper_layer_ctx;
+ ((optiga_comms_t*)upper_layer_ctx)->upper_layer_handler(ctx,event);
+ ((optiga_comms_t*)upper_layer_ctx)->state = OPTIGA_COMMS_FREE;
+}
+
+/// @endcond
+/**
+* @}
+*/
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/pal/nrf5x/pal_gpio.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/pal/nrf5x/pal_gpio.c
new file mode 100644
index 0000000..d4243d8
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/pal/nrf5x/pal_gpio.c
@@ -0,0 +1,97 @@
+/**
+* \copyright
+* Copyright (c) 2018, Infineon Technologies AG
+* All rights reserved.
+*
+* This software is provided with terms and conditions as specified in OPTIGA(TM) Trust X Evaluation Kit License Agreement.
+* \endcopyright
+*
+* \author Infineon AG
+*
+* \file
+*
+* \brief This file implements the platform abstraction layer APIs for gpio.
+*
+* \addtogroup grPAL
+* @{
+*/
+
+
+/**********************************************************************************************************************
+ * HEADER FILES
+ *********************************************************************************************************************/
+#include "pal_gpio.h"
+#include "nrf_gpio.h"
+#include "pal_ifx_i2c_config.h"
+
+/**********************************************************************************************************************
+ * MACROS
+ *********************************************************************************************************************/
+
+/**********************************************************************************************************************
+ * LOCAL DATA
+ *********************************************************************************************************************/
+
+/**********************************************************************************************************************
+ * LOCAL ROUTINES
+ *********************************************************************************************************************/
+
+/**********************************************************************************************************************
+ * API IMPLEMENTATION
+ *********************************************************************************************************************/
+
+void pal_gpio_init()
+{
+ // Init power pins
+ nrf_gpio_cfg_output(19);
+ nrf_gpio_cfg_output(20);
+
+ // Set power pins to enable power
+ nrf_gpio_pin_clear(19); // Enable power for the *on-board* Trust X device
+ nrf_gpio_pin_set(20); // Disable power for *external* Trust X device inside the 2GO slot
+
+ // Init reset pin
+ nrf_gpio_cfg_output((uint32_t)(optiga_reset_0.p_gpio_hw));
+}
+
+/**
+* Sets the GPIO pin to high state
+*
+* <b>API Details:</b>
+* The API sets the pin high, only if the pin is assigned to a valid gpio context.<br>
+* Otherwise the API returns without any failure status.<br>
+*
+*\param[in] p_gpio_context Pointer to pal layer gpio context
+*
+*
+*/
+void pal_gpio_set_high(const pal_gpio_t* p_gpio_context)
+{
+ if (p_gpio_context != NULL && p_gpio_context->p_gpio_hw != NULL)
+ {
+ nrf_gpio_pin_set((uint32_t)(p_gpio_context->p_gpio_hw));
+ }
+}
+
+/**
+* Sets the gpio pin to low state
+*
+* <b>API Details:</b>
+* The API set the pin low, only if the pin is assigned to a valid gpio context.<br>
+* Otherwise the API returns without any failure status.<br>
+*
+*\param[in] p_gpio_context Pointer to pal layer gpio context
+*
+*/
+void pal_gpio_set_low(const pal_gpio_t* p_gpio_context)
+{
+ if (p_gpio_context != NULL && p_gpio_context->p_gpio_hw != NULL)
+ {
+ nrf_gpio_pin_clear((uint32_t)(p_gpio_context->p_gpio_hw));
+ }
+}
+
+/**
+* @}
+*/
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/pal/nrf5x/pal_i2c.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/pal/nrf5x/pal_i2c.c
new file mode 100644
index 0000000..24897ba
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/pal/nrf5x/pal_i2c.c
@@ -0,0 +1,314 @@
+/**
+* \copyright
+* Copyright(c) 2018, Infineon Technologies AG
+* All rights reserved.
+*
+* This software is provided with terms and conditions as specified in OPTIGA(TM) Trust X Evaluation Kit License Agreement.
+* \endcopyright
+*
+* \author Infineon AG
+*
+* \file
+*
+* \brief This file implements the platform abstraction layer(pal) APIs for I2C.
+*
+* \addtogroup grPAL
+* @{
+*/
+
+/**********************************************************************************************************************
+ * HEADER FILES
+ *********************************************************************************************************************/
+#include "pal_i2c.h"
+#include "ifx_i2c.h"
+#include "nrf_twi_mngr.h"
+
+/// @cond hidden
+
+/**********************************************************************************************************************
+ * MACROS
+ *********************************************************************************************************************/
+#define PAL_I2C_MASTER_MAX_BITRATE (400)
+
+/** @brief PIN for I2C SCL to Infineon OPTIGA Trust X device */
+#define OPTIGA_PIN_I2C_SCL (27)
+/** @brief PIN for I2C SDA to Infineon OPTIGA Trust X device */
+#define OPTIGA_PIN_I2C_SDA (26)
+
+/** @brief I2C driver instance */
+#define TWI_INSTANCE_ID 0
+
+/** @brief Maximal number of pending I2C transactions */
+#define MAX_PENDING_TRANSACTIONS 5
+
+/*********************************************************************************************************************
+ * LOCAL DATA
+ *********************************************************************************************************************/
+
+/* Pointer to the current pal i2c context */
+static pal_i2c_t * gp_pal_i2c_current_ctx;
+
+/** @brief Definition of TWI manager instance */
+NRF_TWI_MNGR_DEF(m_app_twi, MAX_PENDING_TRANSACTIONS, TWI_INSTANCE_ID);
+
+/** @brief Definition of TWI manager transfer instance */
+static nrf_twi_mngr_transfer_t m_transfer;
+
+/** @brief Definition of TWI manager transaction instance */
+static nrf_twi_mngr_transaction_t m_transaction;
+
+/**********************************************************************************************************************
+ * LOCAL ROUTINES
+ *********************************************************************************************************************/
+
+/**
+ * Pal I2C event handler function to invoke the registered upper layer callback<br>
+ *
+ *<b>API Details:</b>
+ * - This function implements the platform specific i2c event handling mechanism<br>
+ * - It calls the registered upper layer function after completion of the I2C read/write operations<br>
+ * - The respective event status are explained below.
+ * - #PAL_I2C_EVENT_ERROR when I2C fails due to low level failures(NACK/I2C protocol errors)
+ * - #PAL_I2C_EVENT_SUCCESS when operation is successfully completed
+ *
+ * \param[in] p_pal_i2c_ctx Pointer to the pal i2c context #pal_i2c_t
+ * \param[in] event Status of the event reported after read/write completion or due to I2C errors
+ *
+ */
+static void app_twi_callback(ret_code_t result, void * p_user_data)
+{
+ app_event_handler_t upper_layer_handler;
+ //lint --e{611} suppress "void* function pointer is type casted to app_event_handler_t type"
+ upper_layer_handler = (app_event_handler_t)gp_pal_i2c_current_ctx->upper_layer_event_handler;
+
+ if (result == NRF_SUCCESS)
+ {
+ upper_layer_handler(gp_pal_i2c_current_ctx->upper_layer_ctx, PAL_I2C_EVENT_SUCCESS);
+ }
+ else
+ {
+ upper_layer_handler(gp_pal_i2c_current_ctx->upper_layer_ctx, PAL_I2C_EVENT_ERROR);
+ }
+}
+
+/// @endcond
+
+/**********************************************************************************************************************
+ * API IMPLEMENTATION
+ *********************************************************************************************************************/
+
+/**
+ * API to initialize the i2c master with the given context.
+ * <br>
+ *
+ *<b>API Details:</b>
+ * - The platform specific initialization of I2C master has to be implemented as part of this API, if required.<br>
+ * - If the target platform does not demand explicit initialization of i2c master
+ * (Example: If the platform driver takes care of init after the reset), it would not be required to implement.<br>
+ * - The implementation must take care the following scenarios depending upon the target platform selected.
+ * - The implementation must handle the acquiring and releasing of the I2C bus before initializing the I2C master to
+ * avoid interrupting the ongoing slave I2C transactions using the same I2C master.
+ * - If the I2C bus is in busy state, the API must not initialize and return #PAL_STATUS_I2C_BUSY status.
+ * - Repeated initialization must be taken care with respect to the platform requirements. (Example: Multiple users/applications
+ * sharing the same I2C master resource)
+ *
+ *<b>User Input:</b><br>
+ * - The input #pal_i2c_t p_i2c_context must not be NULL.<br>
+ *
+ * \param[in] p_i2c_context Pal i2c context to be initialized
+ *
+ * \retval #PAL_STATUS_SUCCESS Returns when the I2C master init it successfull
+ * \retval #PAL_STATUS_FAILURE Returns when the I2C init fails.
+ */
+pal_status_t pal_i2c_init(const pal_i2c_t* p_i2c_context)
+{
+ nrf_drv_twi_config_t const config = {
+ .scl = OPTIGA_PIN_I2C_SCL,
+ .sda = OPTIGA_PIN_I2C_SDA,
+ .frequency = (nrf_drv_twi_frequency_t) NRF_TWI_FREQ_400K,
+ .interrupt_priority = APP_IRQ_PRIORITY_LOWEST,
+ .clear_bus_init = false
+ };
+
+ // Initialize I2C driver
+ if (nrf_twi_mngr_init(&m_app_twi, &config) != NRF_SUCCESS)
+ {
+ return PAL_STATUS_FAILURE;
+ }
+ return PAL_STATUS_SUCCESS;
+}
+
+/**
+ * API to de-initialize the I2C master with the specified context.
+ * <br>
+ *
+ *<b>API Details:</b>
+ * - The platform specific de-initialization of I2C master has to be implemented as part of this API, if required.<br>
+ * - If the target platform does not demand explicit de-initialization of i2c master
+ * (Example: If the platform driver takes care of init after the reset), it would not be required to implement.<br>
+ * - The implementation must take care the following scenarios depending upon the target platform selected.
+ * - The implementation must handle the acquiring and releasing of the I2C bus before de-initializing the I2C master to
+ * avoid interrupting the ongoing slave I2C transactions using the same I2C master.
+ * - If the I2C bus is in busy state, the API must not de-initialize and return #PAL_STATUS_I2C_BUSY status.
+ * - This API must ensure that multiple users/applications sharing the same I2C master resource is not impacted.
+ *
+ *<b>User Input:</b><br>
+ * - The input #pal_i2c_t p_i2c_context must not be NULL.<br>
+ *
+ * \param[in] p_i2c_context I2C context to be de-initialized
+ *
+ * \retval #PAL_STATUS_SUCCESS Returns when the I2C master de-init it successfull
+ * \retval #PAL_STATUS_FAILURE Returns when the I2C de-init fails.
+ */
+pal_status_t pal_i2c_deinit(const pal_i2c_t* p_i2c_context)
+{
+ nrf_twi_mngr_uninit(&m_app_twi);
+ return PAL_STATUS_SUCCESS;
+}
+
+/**
+ * Platform abstraction layer API to write the data to I2C slave.
+ * <br>
+ * <br>
+ * \image html pal_i2c_write.png "pal_i2c_write()" width=20cm
+ *
+ *
+ *<b>API Details:</b>
+ * - The API attempts to write if the I2C bus is free, else it returns busy status #PAL_STATUS_I2C_BUSY<br>
+ * - The bus is released only after the completion of transmission or after completion of error handling.<br>
+ * - The API invokes the upper layer handler with the respective event status as explained below.
+ * - #PAL_I2C_EVENT_BUSY when I2C bus in busy state
+ * - #PAL_I2C_EVENT_ERROR when API fails
+ * - #PAL_I2C_EVENT_SUCCESS when operation is successfully completed asynchronously
+ *<br>
+ *
+ *<b>User Input:</b><br>
+ * - The input #pal_i2c_t p_i2c_context must not be NULL.<br>
+ * - The upper_layer_event_handler must be initialized in the p_i2c_context before invoking the API.<br>
+ *
+ *<b>Notes:</b><br>
+ * - Otherwise the below implementation has to be updated to handle different bitrates based on the input context.<br>
+ * - The caller of this API must take care of the guard time based on the slave's requirement.<br>
+ *
+ * \param[in] p_i2c_context Pointer to the pal I2C context #pal_i2c_t
+ * \param[in] p_data Pointer to the data to be written
+ * \param[in] length Length of the data to be written
+ *
+ * \retval #PAL_STATUS_SUCCESS Returns when the I2C write is invoked successfully
+ * \retval #PAL_STATUS_FAILURE Returns when the I2C write fails.
+ * \retval #PAL_STATUS_I2C_BUSY Returns when the I2C bus is busy.
+ */
+pal_status_t pal_i2c_write(pal_i2c_t* p_i2c_context,uint8_t* p_data , uint16_t length)
+{
+ gp_pal_i2c_current_ctx = p_i2c_context;
+
+ m_transfer.p_data = p_data;
+ m_transfer.length = length;
+ m_transfer.operation = NRF_TWI_MNGR_WRITE_OP(IFX_I2C_BASE_ADDR);
+ m_transfer.flags = 0;
+
+ m_transaction.callback = app_twi_callback;
+ m_transaction.number_of_transfers = 1;
+ m_transaction.p_required_twi_cfg = NULL;
+ m_transaction.p_transfers = &m_transfer;
+ m_transaction.p_user_data = (void*) PAL_STATUS_SUCCESS;
+
+ if (nrf_twi_mngr_schedule(&m_app_twi, &m_transaction) != NRF_SUCCESS)
+ {
+ app_twi_callback(NRF_ERROR_BUSY, 0);
+ }
+
+ return PAL_STATUS_SUCCESS;
+}
+
+/**
+ * Platform abstraction layer API to read the data from I2C slave.
+ * <br>
+ * <br>
+ * \image html pal_i2c_read.png "pal_i2c_read()" width=20cm
+ *
+ *<b>API Details:</b>
+ * - The API attempts to read if the I2C bus is free, else it returns busy status #PAL_STATUS_I2C_BUSY<br>
+ * - The bus is released only after the completion of reception or after completion of error handling.<br>
+ * - The API invokes the upper layer handler with the respective event status as explained below.
+ * - #PAL_I2C_EVENT_BUSY when I2C bus in busy state
+ * - #PAL_I2C_EVENT_ERROR when API fails
+ * - #PAL_I2C_EVENT_SUCCESS when operation is successfully completed asynchronously
+ *<br>
+ *
+ *<b>User Input:</b><br>
+ * - The input #pal_i2c_t p_i2c_context must not be NULL.<br>
+ * - The upper_layer_event_handler must be initialized in the p_i2c_context before invoking the API.<br>
+ *
+ *<b>Notes:</b><br>
+ * - Otherwise the below implementation has to be updated to handle different bitrates based on the input context.<br>
+ * - The caller of this API must take care of the guard time based on the slave's requirement.<br>
+ *
+ * \param[in] p_i2c_context pointer to the PAL i2c context #pal_i2c_t
+ * \param[in] p_data Pointer to the data buffer to store the read data
+ * \param[in] length Length of the data to be read
+ *
+ * \retval #PAL_STATUS_SUCCESS Returns when the I2C read is invoked successfully
+ * \retval #PAL_STATUS_FAILURE Returns when the I2C read fails.
+ * \retval #PAL_STATUS_I2C_BUSY Returns when the I2C bus is busy.
+ */
+pal_status_t pal_i2c_read(pal_i2c_t* p_i2c_context , uint8_t* p_data , uint16_t length)
+{
+ gp_pal_i2c_current_ctx = p_i2c_context;
+
+ m_transfer.p_data = p_data;
+ m_transfer.length = length;
+ m_transfer.operation = NRF_TWI_MNGR_READ_OP(IFX_I2C_BASE_ADDR);
+ m_transfer.flags = 0;
+
+ m_transaction.callback = app_twi_callback;
+ m_transaction.number_of_transfers = 1;
+ m_transaction.p_required_twi_cfg = 0;
+ m_transaction.p_transfers = &m_transfer;
+ m_transaction.p_user_data = (void*) PAL_STATUS_SUCCESS;
+
+ if (nrf_twi_mngr_schedule(&m_app_twi, &m_transaction) != NRF_SUCCESS)
+ {
+ app_twi_callback(NRF_ERROR_BUSY, 0);
+ }
+
+ return PAL_STATUS_SUCCESS;
+}
+
+/**
+ * Platform abstraction layer API to set the bitrate/speed(KHz) of I2C master.
+ * <br>
+ *
+ *<b>API Details:</b>
+ * - Sets the bitrate of I2C master if the I2C bus is free, else it returns busy status #PAL_STATUS_I2C_BUSY<br>
+ * - The bus is released after the setting the bitrate.<br>
+ * - This API must take care of setting the bitrate to I2C master's maximum supported value.
+ * - Eg. In XMC4500, the maximum supported bitrate is 400 KHz. If the supplied bitrate is greater than 400KHz, the API will
+ * set the I2C master's bitrate to 400KHz.
+ * - Use the #PAL_I2C_MASTER_MAX_BITRATE macro to specify the maximum supported bitrate value for the target platform.
+ * - If upper_layer_event_handler is initialized, the upper layer handler is invoked with the respective event
+ * status listed below.
+ * - #PAL_I2C_EVENT_BUSY when I2C bus in busy state
+ * - #PAL_I2C_EVENT_ERROR when API fails to set the bit rate
+ * - #PAL_I2C_EVENT_SUCCESS when operation is successful
+ *<br>
+ *
+ *<b>User Input:</b><br>
+ * - The input #pal_i2c_t p_i2c_context must not be NULL.<br>
+ *
+ * \param[in] p_i2c_context Pointer to the pal i2c context
+ * \param[in] bitrate Bitrate to be used by i2c master in KHz
+ *
+ * \retval #PAL_STATUS_SUCCESS Returns when the setting of bitrate is successfully completed
+ * \retval #PAL_STATUS_FAILURE Returns when the setting of bitrate fails.
+ * \retval #PAL_STATUS_I2C_BUSY Returns when the I2C bus is busy.
+ */
+pal_status_t pal_i2c_set_bitrate(const pal_i2c_t* p_i2c_context , uint16_t bitrate)
+{
+ // Bitrate is fixed to the maximum frequency on this platform (400K)
+ return PAL_STATUS_SUCCESS;
+}
+
+/**
+* @}
+*/
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/pal/nrf5x/pal_ifx_i2c_config.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/pal/nrf5x/pal_ifx_i2c_config.c
new file mode 100644
index 0000000..bb4b51f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/pal/nrf5x/pal_ifx_i2c_config.c
@@ -0,0 +1,71 @@
+/**
+* \copyright
+* Copyright(c) 2018, Infineon Technologies AG
+* All rights reserved.
+*
+* This software is provided with terms and conditions as specified in OPTIGA(RM) Trust X Evaluation Kit License Agreement.
+* \endcopyright
+*
+* \author Infineon AG
+*
+* \file
+*
+* \brief This file implements platform abstraction layer configurations for ifx i2c protocol.
+*
+* \addtogroup grPAL
+* @{
+*/
+
+/**********************************************************************************************************************
+ * HEADER FILES
+ *********************************************************************************************************************/
+#include "stdlib.h"
+#include "stdio.h"
+#include "pal_gpio.h"
+#include "pal_i2c.h"
+#include "ifx_i2c_config.h"
+
+/*********************************************************************************************************************
+ * pal ifx i2c instance
+ *********************************************************************************************************************/
+/**
+ * \brief PAL I2C configuration for OPTIGA.
+ */
+pal_i2c_t optiga_pal_i2c_context_0 =
+{
+ /// Pointer to I2C master platform specific context
+ NULL,
+ /// Slave address
+ IFX_I2C_BASE_ADDR,
+ /// Upper layer context
+ NULL,
+ /// Callback event handler
+ NULL
+};
+
+/*********************************************************************************************************************
+ * PAL GPIO configurations defined for XMC4500
+ *********************************************************************************************************************/
+/**
+* \brief PAL vdd pin configuration for OPTIGA.
+ */
+pal_gpio_t optiga_vdd_0 =
+{
+ // Platform specific GPIO context for the pin used to toggle Vdd.
+ (void*)NULL
+};
+
+/**
+ * \brief PAL reset pin configuration for OPTIGA.
+ */
+pal_gpio_t optiga_reset_0 =
+{
+ // Platform specific GPIO context for the pin used to toggle Reset.
+ (void*)18
+};
+
+
+/**
+* @}
+*/
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/pal/nrf5x/pal_os_event.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/pal/nrf5x/pal_os_event.c
new file mode 100644
index 0000000..809c2bd
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/pal/nrf5x/pal_os_event.c
@@ -0,0 +1,127 @@
+/**
+* \copyright
+* Copyright(c) 2018, Infineon Technologies AG
+* All rights reserved.
+*
+* This software is provided with terms and conditions as specified in OPTIGA(TM) Trust X Evaluation Kit License Agreement.
+* \endcopyright
+*
+* \author Infineon AG
+*
+* \file
+*
+* \brief This file implements the platform abstraction layer APIs for os event/scheduler.
+*
+* \addtogroup grPAL
+* @{
+*/
+
+/**********************************************************************************************************************
+ * HEADER FILES
+ *********************************************************************************************************************/
+#include "stdlib.h"
+#include "stdio.h"
+#include "pal_os_event.h"
+#include "nrf_rtc.h"
+#include "nrf_drv_rtc.h"
+
+/**********************************************************************************************************************
+ * MACROS
+ *********************************************************************************************************************/
+
+/*********************************************************************************************************************
+ * LOCAL DATA
+ *********************************************************************************************************************/
+/// @cond hidden
+/// Callback function when timer elapses
+static volatile register_callback callback_registered = NULL;
+/// Pointer to store upper layer callback context (For example: Ifx i2c context)
+static void * callback_ctx;
+
+const nrf_drv_rtc_t rtc2 = NRF_DRV_RTC_INSTANCE(2);
+static nrf_drv_rtc_config_t m_rtc2_config = NRF_DRV_RTC_DEFAULT_CONFIG;
+
+// Tick count for pal_os_timer
+volatile uint32_t g_tick_count = 0;
+
+/**
+* Timer callback handler.
+*
+* This get called from the TIMER elapse event.<br>
+* Once the timer expires, the registered callback funtion gets called from the timer event handler, if
+* the call back is not NULL.<br>
+*
+*\param[in] args Callback argument
+*
+*/
+static void ifx_rtc_handler(nrf_drv_rtc_int_type_t int_type)
+{
+ volatile register_callback callback;
+
+ if (int_type == NRF_DRV_RTC_INT_TICK)
+ {
+ g_tick_count++;
+ }
+
+ if (int_type == NRF_DRV_RTC_INT_COMPARE0)
+ {
+ nrf_drv_rtc_cc_disable(&rtc2, 0);
+
+ if (callback_registered != NULL)
+ {
+ callback = callback_registered;
+ callback_registered = NULL;
+ callback(callback_ctx);
+ }
+ }
+}
+
+/// @endcond
+
+void pal_os_event_init()
+{
+ // Initialize the RTC2 driver instance
+ APP_ERROR_CHECK(nrf_drv_rtc_init(&rtc2, &m_rtc2_config, ifx_rtc_handler));
+
+ // Set the prescaler to approximately get 1 ms intervals
+ m_rtc2_config.prescaler = 31;
+
+ // Enable tick event and interrupt
+ nrf_drv_rtc_tick_enable(&rtc2, true);
+
+ // Power on RTC instance
+ nrf_drv_rtc_enable(&rtc2);
+}
+
+/**
+* Platform specific event call back registration function to trigger once when timer expires.
+* <br>
+*
+* <b>API Details:</b>
+* This function registers the callback function supplied by the caller.<br>
+* It triggers a timer with the supplied time interval in microseconds.<br>
+* Once the timer expires, the registered callback function gets called.<br>
+*
+* \param[in] callback Callback function pointer
+* \param[in] callback_args Callback arguments
+* \param[in] time_us time in micro seconds to trigger the call back
+*
+*/
+void pal_os_event_register_callback_oneshot(register_callback callback,
+ void* callback_args,
+ uint32_t time_us)
+{
+ callback_registered = callback;
+ callback_ctx = callback_args;
+
+ // Clear the counter
+ nrf_drv_rtc_counter_clear(&rtc2);
+
+ // Set the compare register to trigger approximately at time_us
+ APP_ERROR_CHECK(nrf_drv_rtc_cc_set(&rtc2, 0, (time_us / 1024) + 1 , true));
+}
+
+/**
+* @}
+*/
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/pal/nrf5x/pal_os_timer.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/pal/nrf5x/pal_os_timer.c
new file mode 100644
index 0000000..da2deba
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/infineon/pal/nrf5x/pal_os_timer.c
@@ -0,0 +1,71 @@
+/**
+* \copyright
+* Copyright (c) 2018, Infineon Technologies AG
+* All rights reserved.
+*
+* This software is provided with terms and conditions as specified in OPTIGA(TM) Trust X Evaluation Kit License Agreement.
+* \endcopyright
+*
+* \author Infineon AG
+*
+* \file
+*
+* \brief This file implements the platform abstraction layer APIs for timer.
+*
+* \addtogroup grPAL
+* @{
+*/
+
+/**********************************************************************************************************************
+ * HEADER FILES
+ *********************************************************************************************************************/
+#include "pal_os_timer.h"
+#include "nrf_delay.h"
+#include "nrf_rtc.h"
+#include "nrf_drv_rtc.h"
+
+/**********************************************************************************************************************
+ * MACROS
+ *********************************************************************************************************************/
+
+/// @cond hidden
+/*********************************************************************************************************************
+ * LOCAL DATA
+ *********************************************************************************************************************/
+// Defined in pal_os_event.c
+extern volatile uint32_t g_tick_count;
+
+/**********************************************************************************************************************
+ * LOCAL ROUTINES
+ *********************************************************************************************************************/
+/// @endcond
+
+/**********************************************************************************************************************
+ * API IMPLEMENTATION
+ *********************************************************************************************************************/
+/**
+* Get the current time in milliseconds<br>
+*
+*
+* \retval uint32_t time in milliseconds
+*/
+uint32_t pal_os_timer_get_time_in_milliseconds(void)
+{
+ return (g_tick_count);
+}
+
+/**
+* Function to wait or delay until the given milliseconds time
+*
+* \param[in] milliseconds Delay value in milliseconds
+*
+*/
+void pal_os_timer_delay_in_milliseconds(uint16_t milliseconds)
+{
+ nrf_delay_ms(milliseconds);
+}
+
+/**
+* @}
+*/
+