All source files: license disclaimer text update and add link to the License file on ST Internet.
V3.6.0 / 27-January-2012
+
Main
+Changes
+
+
Update directory structure to be compliant with CMSIS V2.1
All source files: update disclaimer to add reference to the new license agreement
stm32f10x.h
Add define for Cortex-M3 revision __CM3_REV
Allow
+modification of some constants by the application code, definition of
+these constants is now bracketed by #if !defined. The concerned constant are HSE_VALUE, HSI_VALUE and HSE_STARTUP_TIMEOUT
Add missing bits definition for DAC CR register
Add missing bits definition for FSMC BTR1, BTR2, BTR3, BWTR1, BWTR2, BWTR3 and BWTR4 registers
Definition for Flash keys moved from stm32f10x_flash.c to stm32f10x.h
Add startup file for TASKING toolchain
V3.5.0 (based CMSIS V1.3) vs. V3.6.0 (based on CMSIS V2.1) compatibility update
Due to the directory structure difference between CMSIS V1.3 and V2.1, when migrating a project based on STM32F10x drivers V3.5.0 to V3.6.0 you need to perform the following update:
In
+the compiler preprocessor, remove CortexM3 CMSIS include path. CortexM3
+CMSIS files are included by default in your development toolchain
Remove core_cm3.c file (if it is used). Almost of CortexM3 CMSIS function are provided as intrinsic by the compiler
In the compiler preprocessor, update path of STM32F10x CMSISinclude files from Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x toLibraries\CMSIS\Device\ST\STM32F10x\Include
In the project settings, update path of startup_stm32f10x_xx.s file from Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\startup\”Compiler” to Libraries\CMSIS\Device\ST\STM32F10x\Source\Templates\”Compiler”
where, "Compiler" refer to arm, gcc_ride7, iar, TASKING or TrueSTUDIO
+
V3.5.0 / 11-March-2011
+
Main
+Changes
+
+
+
stm32f10x.h
+and startup_stm32f10x_hd_vl.s files: remove the FSMC interrupt
+definition for STM32F10x High-density Value line devices.
+
+
system_stm32f10x.c file provided within the CMSIS folder.
+
+
+
+
+
3.4.0
+- 10/15/2010
+
+
+
General
+
+
+
+
Add support
+for STM32F10x High-density Value line devices.
+
+ All
+STM32 devices definitions are commented by default. User has to select the
+appropriate device before starting else an error will be signaled on compile
+time.
+
Add new IRQs definitions inside the IRQn_Type enumeration for STM23 High-density Value line devices.
+
"bool" type removed.
+
+
STM32F10x CMSIS Cortex-M3 Device Peripheral Access Layer System Files:system_stm32f10x.h and system_stm32f10x.c
+
+
+
"system_stm32f10x.c" moved to to "STM32F10x_StdPeriph_Template" directory. This file is also moved to each example directory under "STM32F10x_StdPeriph_Examples".
+
+
SystemInit_ExtMemCtl() function: update to support High-density Value line devices.
+
Add "VECT_TAB_SRAM" inside "system_stm32f10x.c"
+to select if the user want to place the Vector Table in internal SRAM.
+An additional define is also to specify the Vector Table offset "VECT_TAB_OFFSET".
+
Update
+the stm32f10x.h file to support new Value line devices features: CEC
+peripheral, new General purpose timers TIM15, TIM16 and TIM17.
+
Peripherals Bits definitions updated to be in line with Value line devices available features.
+
+
HSE_Value,
+HSI_Value and HSEStartup_TimeOut changed to upper case: HSE_VALUE,
+HSI_VALUE and HSE_STARTUP_TIMEOUT. Old names are kept for legacy
+purposes.
+
+
+
STM32F10x CMSIS Cortex-M3 Device Peripheral Access Layer System Files:system_stm32f10x.h and system_stm32f10x.c
+
+
+
SystemFrequency variable name changed to SystemCoreClock
+
+
Default
+ SystemCoreClock is changed to 24MHz when Value line devices are selected and to 72MHz on other devices.
+
+
All while(1) loop were removed from all clock setting functions. User has to handle the HSE startup failure.
+
+
Additional function void SystemCoreClockUpdate (void) is provided.
+
Add new
+startup files for STM32 Low-density Value line devices:
+ startup_stm32f10x_ld_vl.s
+
Add new startup
+files for STM32 Medium-density Value line devices:
+ startup_stm32f10x_md_vl.s
+
SystemInit() function is called from startup file (startup_stm32f10x_xx.s) before to branch to application main.
+To reconfigure the default setting of SystemInit() function, refer to system_stm32f10x.c file
+
+
GNU startup file for Low density devices (startup_stm32f10x_ld.s) is updated to fix compilation errors.
+
+
+
+
+
+
+
+
License
+
Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); You may not use this package except in compliance with the License. You may obtain a copy of the License at:
Unless
+required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See
+the License for the specific language governing permissions and
+limitations under the License.
+
+
+
For
+complete documentation on STM32 Microcontrollers
+visit www.st.com/STM32
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Libraries/CMSIS/Include/arm_common_tables.h b/Libraries/CMSIS/Include/arm_common_tables.h
new file mode 100644
index 0000000..7245c4f
--- /dev/null
+++ b/Libraries/CMSIS/Include/arm_common_tables.h
@@ -0,0 +1,35 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010 ARM Limited. All rights reserved.
+*
+* $Date: 11. November 2010
+* $Revision: V1.0.2
+*
+* Project: CMSIS DSP Library
+* Title: arm_common_tables.h
+*
+* Description: This file has extern declaration for common tables like Bitreverse, reciprocal etc which are used across different functions
+*
+* Target Processor: Cortex-M4/Cortex-M3
+*
+* Version 1.0.2 2010/11/11
+* Documentation updated.
+*
+* Version 1.0.1 2010/10/05
+* Production release and review comments incorporated.
+*
+* Version 1.0.0 2010/09/20
+* Production release and review comments incorporated.
+* -------------------------------------------------------------------- */
+
+#ifndef _ARM_COMMON_TABLES_H
+#define _ARM_COMMON_TABLES_H
+
+#include "arm_math.h"
+
+extern uint16_t armBitRevTable[256];
+extern q15_t armRecipTableQ15[64];
+extern q31_t armRecipTableQ31[64];
+extern const q31_t realCoefAQ31[1024];
+extern const q31_t realCoefBQ31[1024];
+
+#endif /* ARM_COMMON_TABLES_H */
diff --git a/Libraries/CMSIS/Include/arm_math.h b/Libraries/CMSIS/Include/arm_math.h
new file mode 100644
index 0000000..ffa03b6
--- /dev/null
+++ b/Libraries/CMSIS/Include/arm_math.h
@@ -0,0 +1,7051 @@
+/* ----------------------------------------------------------------------
+ * Copyright (C) 2010 ARM Limited. All rights reserved.
+ *
+ * $Date: 15. July 2011
+ * $Revision: V1.0.10
+ *
+ * Project: CMSIS DSP Library
+ * Title: arm_math.h
+ *
+ * Description: Public header file for CMSIS DSP Library
+ *
+ * Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+ *
+ * Version 1.0.10 2011/7/15
+ * Big Endian support added and Merged M0 and M3/M4 Source code.
+ *
+ * Version 1.0.3 2010/11/29
+ * Re-organized the CMSIS folders and updated documentation.
+ *
+ * Version 1.0.2 2010/11/11
+ * Documentation updated.
+ *
+ * Version 1.0.1 2010/10/05
+ * Production release and review comments incorporated.
+ *
+ * Version 1.0.0 2010/09/20
+ * Production release and review comments incorporated.
+ * -------------------------------------------------------------------- */
+
+/**
+ \mainpage CMSIS DSP Software Library
+ *
+ * Introduction
+ *
+ * This user manual describes the CMSIS DSP software library,
+ * a suite of common signal processing functions for use on Cortex-M processor based devices.
+ *
+ * The library is divided into a number of modules each covering a specific category:
+ * - Basic math functions
+ * - Fast math functions
+ * - Complex math functions
+ * - Filters
+ * - Matrix functions
+ * - Transforms
+ * - Motor control functions
+ * - Statistical functions
+ * - Support functions
+ * - Interpolation functions
+ *
+ * The library has separate functions for operating on 8-bit integers, 16-bit integers,
+ * 32-bit integer and 32-bit floating-point values.
+ *
+ * Processor Support
+ *
+ * The library is completely written in C and is fully CMSIS compliant.
+ * High performance is achieved through maximum use of Cortex-M4 intrinsics.
+ *
+ * The supplied library source code also builds and runs on the Cortex-M3 and Cortex-M0 processor,
+ * with the DSP intrinsics being emulated through software.
+ *
+ *
+ * Toolchain Support
+ *
+ * The library has been developed and tested with MDK-ARM version 4.21.
+ * The library is being tested in GCC and IAR toolchains and updates on this activity will be made available shortly.
+ *
+ * Using the Library
+ *
+ * The library installer contains prebuilt versions of the libraries in the Lib folder.
+ * - arm_cortexM4lf_math.lib (Little endian and Floating Point Unit on Cortex-M4)
+ * - arm_cortexM4bf_math.lib (Big endian and Floating Point Unit on Cortex-M4)
+ * - arm_cortexM4l_math.lib (Little endian on Cortex-M4)
+ * - arm_cortexM4b_math.lib (Big endian on Cortex-M4)
+ * - arm_cortexM3l_math.lib (Little endian on Cortex-M3)
+ * - arm_cortexM3b_math.lib (Big endian on Cortex-M3)
+ * - arm_cortexM0l_math.lib (Little endian on Cortex-M0)
+ * - arm_cortexM0b_math.lib (Big endian on Cortex-M3)
+ *
+ * The library functions are declared in the public file arm_math.h which is placed in the Include folder.
+ * Simply include this file and link the appropriate library in the application and begin calling the library functions. The Library supports single
+ * public header file arm_math.h for Cortex-M4/M3/M0 with little endian and big endian. Same header file will be used for floating point unit(FPU) variants.
+ * Define the appropriate pre processor MACRO ARM_MATH_CM4 or ARM_MATH_CM3 or
+ * ARM_MATH_CM0 depending on the target processor in the application.
+ *
+ * Examples
+ *
+ * The library ships with a number of examples which demonstrate how to use the library functions.
+ *
+ * Building the Library
+ *
+ * The library installer contains project files to re build libraries on MDK Tool chain in the CMSIS\DSP_Lib\Source\ARM folder.
+ * - arm_cortexM0b_math.uvproj
+ * - arm_cortexM0l_math.uvproj
+ * - arm_cortexM3b_math.uvproj
+ * - arm_cortexM3l_math.uvproj
+ * - arm_cortexM4b_math.uvproj
+ * - arm_cortexM4l_math.uvproj
+ * - arm_cortexM4bf_math.uvproj
+ * - arm_cortexM4lf_math.uvproj
+ *
+ * Each library project have differant pre-processor macros.
+ *
+ * ARM_MATH_CMx:
+ * Define macro ARM_MATH_CM4 for building the library on Cortex-M4 target, ARM_MATH_CM3 for building library on Cortex-M3 target
+ * and ARM_MATH_CM0 for building library on cortex-M0 target.
+ *
+ * ARM_MATH_BIG_ENDIAN:
+ * Define macro ARM_MATH_BIG_ENDIAN to build the library for big endian targets. By default library builds for little endian targets.
+ *
+ * ARM_MATH_MATRIX_CHECK:
+ * Define macro for checking on the input and output sizes of matrices
+ *
+ * ARM_MATH_ROUNDING:
+ * Define macro for rounding on support functions
+ *
+ * __FPU_PRESENT:
+ * Initialize macro __FPU_PRESENT = 1 when building on FPU supported Targets. Enable this macro for M4bf and M4lf libraries
+ *
+ *
+ * The project can be built by opening the appropriate project in MDK-ARM 4.21 chain and defining the optional pre processor MACROs detailed above.
+ *
+ * Copyright Notice
+ *
+ * Copyright (C) 2010 ARM Limited. All rights reserved.
+ */
+
+
+/**
+ * @defgroup groupMath Basic Math Functions
+ */
+
+/**
+ * @defgroup groupFastMath Fast Math Functions
+ * This set of functions provides a fast approximation to sine, cosine, and square root.
+ * As compared to most of the other functions in the CMSIS math library, the fast math functions
+ * operate on individual values and not arrays.
+ * There are separate functions for Q15, Q31, and floating-point data.
+ *
+ */
+
+/**
+ * @defgroup groupCmplxMath Complex Math Functions
+ * This set of functions operates on complex data vectors.
+ * The data in the complex arrays is stored in an interleaved fashion
+ * (real, imag, real, imag, ...).
+ * In the API functions, the number of samples in a complex array refers
+ * to the number of complex values; the array contains twice this number of
+ * real values.
+ */
+
+/**
+ * @defgroup groupFilters Filtering Functions
+ */
+
+/**
+ * @defgroup groupMatrix Matrix Functions
+ *
+ * This set of functions provides basic matrix math operations.
+ * The functions operate on matrix data structures. For example,
+ * the type
+ * definition for the floating-point matrix structure is shown
+ * below:
+ *
+ * typedef struct
+ * {
+ * uint16_t numRows; // number of rows of the matrix.
+ * uint16_t numCols; // number of columns of the matrix.
+ * float32_t *pData; // points to the data of the matrix.
+ * } arm_matrix_instance_f32;
+ *
+ * There are similar definitions for Q15 and Q31 data types.
+ *
+ * The structure specifies the size of the matrix and then points to
+ * an array of data. The array is of size numRows X numCols
+ * and the values are arranged in row order. That is, the
+ * matrix element (i, j) is stored at:
+ *
+ * pData[i*numCols + j]
+ *
+ *
+ * \par Init Functions
+ * There is an associated initialization function for each type of matrix
+ * data structure.
+ * The initialization function sets the values of the internal structure fields.
+ * Refer to the function arm_mat_init_f32(), arm_mat_init_q31()
+ * and arm_mat_init_q15() for floating-point, Q31 and Q15 types, respectively.
+ *
+ * \par
+ * Use of the initialization function is optional. However, if initialization function is used
+ * then the instance structure cannot be placed into a const data section.
+ * To place the instance structure in a const data
+ * section, manually initialize the data structure. For example:
+ *
+ * arm_matrix_instance_f32 S = {nRows, nColumns, pData};
+ * arm_matrix_instance_q31 S = {nRows, nColumns, pData};
+ * arm_matrix_instance_q15 S = {nRows, nColumns, pData};
+ *
+ * where nRows specifies the number of rows, nColumns
+ * specifies the number of columns, and pData points to the
+ * data array.
+ *
+ * \par Size Checking
+ * By default all of the matrix functions perform size checking on the input and
+ * output matrices. For example, the matrix addition function verifies that the
+ * two input matrices and the output matrix all have the same number of rows and
+ * columns. If the size check fails the functions return:
+ *
+ * ARM_MATH_SIZE_MISMATCH
+ *
+ * Otherwise the functions return
+ *
+ * ARM_MATH_SUCCESS
+ *
+ * There is some overhead associated with this matrix size checking.
+ * The matrix size checking is enabled via the #define
+ *
+ * ARM_MATH_MATRIX_CHECK
+ *
+ * within the library project settings. By default this macro is defined
+ * and size checking is enabled. By changing the project settings and
+ * undefining this macro size checking is eliminated and the functions
+ * run a bit faster. With size checking disabled the functions always
+ * return ARM_MATH_SUCCESS.
+ */
+
+/**
+ * @defgroup groupTransforms Transform Functions
+ */
+
+/**
+ * @defgroup groupController Controller Functions
+ */
+
+/**
+ * @defgroup groupStats Statistics Functions
+ */
+/**
+ * @defgroup groupSupport Support Functions
+ */
+
+/**
+ * @defgroup groupInterpolation Interpolation Functions
+ * These functions perform 1- and 2-dimensional interpolation of data.
+ * Linear interpolation is used for 1-dimensional data and
+ * bilinear interpolation is used for 2-dimensional data.
+ */
+
+/**
+ * @defgroup groupExamples Examples
+ */
+#ifndef _ARM_MATH_H
+#define _ARM_MATH_H
+
+#define __CMSIS_GENERIC /* disable NVIC and Systick functions */
+
+#if defined (ARM_MATH_CM4)
+ #include "core_cm4.h"
+#elif defined (ARM_MATH_CM3)
+ #include "core_cm3.h"
+#elif defined (ARM_MATH_CM0)
+ #include "core_cm0.h"
+#else
+#include "ARMCM4.h"
+#warning "Define either ARM_MATH_CM4 OR ARM_MATH_CM3...By Default building on ARM_MATH_CM4....."
+#endif
+
+#undef __CMSIS_GENERIC /* enable NVIC and Systick functions */
+#include "string.h"
+ #include "math.h"
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+ /**
+ * @brief Macros required for reciprocal calculation in Normalized LMS
+ */
+
+#define DELTA_Q31 (0x100)
+#define DELTA_Q15 0x5
+#define INDEX_MASK 0x0000003F
+#define PI 3.14159265358979f
+
+ /**
+ * @brief Macros required for SINE and COSINE Fast math approximations
+ */
+
+#define TABLE_SIZE 256
+#define TABLE_SPACING_Q31 0x800000
+#define TABLE_SPACING_Q15 0x80
+
+ /**
+ * @brief Macros required for SINE and COSINE Controller functions
+ */
+ /* 1.31(q31) Fixed value of 2/360 */
+ /* -1 to +1 is divided into 360 values so total spacing is (2/360) */
+#define INPUT_SPACING 0xB60B61
+
+
+ /**
+ * @brief Error status returned by some functions in the library.
+ */
+
+ typedef enum
+ {
+ ARM_MATH_SUCCESS = 0, /**< No error */
+ ARM_MATH_ARGUMENT_ERROR = -1, /**< One or more arguments are incorrect */
+ ARM_MATH_LENGTH_ERROR = -2, /**< Length of data buffer is incorrect */
+ ARM_MATH_SIZE_MISMATCH = -3, /**< Size of matrices is not compatible with the operation. */
+ ARM_MATH_NANINF = -4, /**< Not-a-number (NaN) or infinity is generated */
+ ARM_MATH_SINGULAR = -5, /**< Generated by matrix inversion if the input matrix is singular and cannot be inverted. */
+ ARM_MATH_TEST_FAILURE = -6 /**< Test Failed */
+ } arm_status;
+
+ /**
+ * @brief 8-bit fractional data type in 1.7 format.
+ */
+ typedef int8_t q7_t;
+
+ /**
+ * @brief 16-bit fractional data type in 1.15 format.
+ */
+ typedef int16_t q15_t;
+
+ /**
+ * @brief 32-bit fractional data type in 1.31 format.
+ */
+ typedef int32_t q31_t;
+
+ /**
+ * @brief 64-bit fractional data type in 1.63 format.
+ */
+ typedef int64_t q63_t;
+
+ /**
+ * @brief 32-bit floating-point type definition.
+ */
+ typedef float float32_t;
+
+ /**
+ * @brief 64-bit floating-point type definition.
+ */
+ typedef double float64_t;
+
+ /**
+ * @brief definition to read/write two 16 bit values.
+ */
+#define __SIMD32(addr) (*(int32_t **) & (addr))
+
+#if defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0)
+ /**
+ * @brief definition to pack two 16 bit values.
+ */
+#define __PKHBT(ARG1, ARG2, ARG3) ( (((int32_t)(ARG1) << 0) & (int32_t)0x0000FFFF) | \
+ (((int32_t)(ARG2) << ARG3) & (int32_t)0xFFFF0000) )
+
+#endif
+
+
+ /**
+ * @brief definition to pack four 8 bit values.
+ */
+#ifndef ARM_MATH_BIG_ENDIAN
+
+#define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v0) << 0) & (int32_t)0x000000FF) | \
+ (((int32_t)(v1) << 8) & (int32_t)0x0000FF00) | \
+ (((int32_t)(v2) << 16) & (int32_t)0x00FF0000) | \
+ (((int32_t)(v3) << 24) & (int32_t)0xFF000000) )
+#else
+
+#define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v3) << 0) & (int32_t)0x000000FF) | \
+ (((int32_t)(v2) << 8) & (int32_t)0x0000FF00) | \
+ (((int32_t)(v1) << 16) & (int32_t)0x00FF0000) | \
+ (((int32_t)(v0) << 24) & (int32_t)0xFF000000) )
+
+#endif
+
+
+ /**
+ * @brief Clips Q63 to Q31 values.
+ */
+ static __INLINE q31_t clip_q63_to_q31(
+ q63_t x)
+ {
+ return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ?
+ ((0x7FFFFFFF ^ ((q31_t) (x >> 63)))) : (q31_t) x;
+ }
+
+ /**
+ * @brief Clips Q63 to Q15 values.
+ */
+ static __INLINE q15_t clip_q63_to_q15(
+ q63_t x)
+ {
+ return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ?
+ ((0x7FFF ^ ((q15_t) (x >> 63)))) : (q15_t) (x >> 15);
+ }
+
+ /**
+ * @brief Clips Q31 to Q7 values.
+ */
+ static __INLINE q7_t clip_q31_to_q7(
+ q31_t x)
+ {
+ return ((q31_t) (x >> 24) != ((q31_t) x >> 23)) ?
+ ((0x7F ^ ((q7_t) (x >> 31)))) : (q7_t) x;
+ }
+
+ /**
+ * @brief Clips Q31 to Q15 values.
+ */
+ static __INLINE q15_t clip_q31_to_q15(
+ q31_t x)
+ {
+ return ((q31_t) (x >> 16) != ((q31_t) x >> 15)) ?
+ ((0x7FFF ^ ((q15_t) (x >> 31)))) : (q15_t) x;
+ }
+
+ /**
+ * @brief Multiplies 32 X 64 and returns 32 bit result in 2.30 format.
+ */
+
+ static __INLINE q63_t mult32x64(
+ q63_t x,
+ q31_t y)
+ {
+ return ((((q63_t) (x & 0x00000000FFFFFFFF) * y) >> 32) +
+ (((q63_t) (x >> 32) * y)));
+ }
+
+
+#if defined (ARM_MATH_CM0) && defined ( __CC_ARM )
+#define __CLZ __clz
+#endif
+
+#if defined (ARM_MATH_CM0) && ((defined (__ICCARM__)) ||(defined (__GNUC__)) || defined (__TASKING__) )
+
+ static __INLINE uint32_t __CLZ(q31_t data);
+
+
+ static __INLINE uint32_t __CLZ(q31_t data)
+ {
+ uint32_t count = 0;
+ uint32_t mask = 0x80000000;
+
+ while((data & mask) == 0)
+ {
+ count += 1u;
+ mask = mask >> 1u;
+ }
+
+ return(count);
+
+ }
+
+#endif
+
+ /**
+ * @brief Function to Calculates 1/in(reciprocal) value of Q31 Data type.
+ */
+
+ static __INLINE uint32_t arm_recip_q31(
+ q31_t in,
+ q31_t * dst,
+ q31_t * pRecipTable)
+ {
+
+ uint32_t out, tempVal;
+ uint32_t index, i;
+ uint32_t signBits;
+
+ if(in > 0)
+ {
+ signBits = __CLZ(in) - 1;
+ }
+ else
+ {
+ signBits = __CLZ(-in) - 1;
+ }
+
+ /* Convert input sample to 1.31 format */
+ in = in << signBits;
+
+ /* calculation of index for initial approximated Val */
+ index = (uint32_t) (in >> 24u);
+ index = (index & INDEX_MASK);
+
+ /* 1.31 with exp 1 */
+ out = pRecipTable[index];
+
+ /* calculation of reciprocal value */
+ /* running approximation for two iterations */
+ for (i = 0u; i < 2u; i++)
+ {
+ tempVal = (q31_t) (((q63_t) in * out) >> 31u);
+ tempVal = 0x7FFFFFFF - tempVal;
+ /* 1.31 with exp 1 */
+ //out = (q31_t) (((q63_t) out * tempVal) >> 30u);
+ out = (q31_t) clip_q63_to_q31(((q63_t) out * tempVal) >> 30u);
+ }
+
+ /* write output */
+ *dst = out;
+
+ /* return num of signbits of out = 1/in value */
+ return (signBits + 1u);
+
+ }
+
+ /**
+ * @brief Function to Calculates 1/in(reciprocal) value of Q15 Data type.
+ */
+ static __INLINE uint32_t arm_recip_q15(
+ q15_t in,
+ q15_t * dst,
+ q15_t * pRecipTable)
+ {
+
+ uint32_t out = 0, tempVal = 0;
+ uint32_t index = 0, i = 0;
+ uint32_t signBits = 0;
+
+ if(in > 0)
+ {
+ signBits = __CLZ(in) - 17;
+ }
+ else
+ {
+ signBits = __CLZ(-in) - 17;
+ }
+
+ /* Convert input sample to 1.15 format */
+ in = in << signBits;
+
+ /* calculation of index for initial approximated Val */
+ index = in >> 8;
+ index = (index & INDEX_MASK);
+
+ /* 1.15 with exp 1 */
+ out = pRecipTable[index];
+
+ /* calculation of reciprocal value */
+ /* running approximation for two iterations */
+ for (i = 0; i < 2; i++)
+ {
+ tempVal = (q15_t) (((q31_t) in * out) >> 15);
+ tempVal = 0x7FFF - tempVal;
+ /* 1.15 with exp 1 */
+ out = (q15_t) (((q31_t) out * tempVal) >> 14);
+ }
+
+ /* write output */
+ *dst = out;
+
+ /* return num of signbits of out = 1/in value */
+ return (signBits + 1);
+
+ }
+
+
+ /*
+ * @brief C custom defined intrinisic function for only M0 processors
+ */
+#if defined(ARM_MATH_CM0)
+
+ static __INLINE q31_t __SSAT(
+ q31_t x,
+ uint32_t y)
+ {
+ int32_t posMax, negMin;
+ uint32_t i;
+
+ posMax = 1;
+ for (i = 0; i < (y - 1); i++)
+ {
+ posMax = posMax * 2;
+ }
+
+ if(x > 0)
+ {
+ posMax = (posMax - 1);
+
+ if(x > posMax)
+ {
+ x = posMax;
+ }
+ }
+ else
+ {
+ negMin = -posMax;
+
+ if(x < negMin)
+ {
+ x = negMin;
+ }
+ }
+ return (x);
+
+
+ }
+
+#endif /* end of ARM_MATH_CM0 */
+
+
+
+ /*
+ * @brief C custom defined intrinsic function for M3 and M0 processors
+ */
+#if defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0)
+
+ /*
+ * @brief C custom defined QADD8 for M3 and M0 processors
+ */
+ static __INLINE q31_t __QADD8(
+ q31_t x,
+ q31_t y)
+ {
+
+ q31_t sum;
+ q7_t r, s, t, u;
+
+ r = (char) x;
+ s = (char) y;
+
+ r = __SSAT((q31_t) (r + s), 8);
+ s = __SSAT(((q31_t) (((x << 16) >> 24) + ((y << 16) >> 24))), 8);
+ t = __SSAT(((q31_t) (((x << 8) >> 24) + ((y << 8) >> 24))), 8);
+ u = __SSAT(((q31_t) ((x >> 24) + (y >> 24))), 8);
+
+ sum = (((q31_t) u << 24) & 0xFF000000) | (((q31_t) t << 16) & 0x00FF0000) |
+ (((q31_t) s << 8) & 0x0000FF00) | (r & 0x000000FF);
+
+ return sum;
+
+ }
+
+ /*
+ * @brief C custom defined QSUB8 for M3 and M0 processors
+ */
+ static __INLINE q31_t __QSUB8(
+ q31_t x,
+ q31_t y)
+ {
+
+ q31_t sum;
+ q31_t r, s, t, u;
+
+ r = (char) x;
+ s = (char) y;
+
+ r = __SSAT((r - s), 8);
+ s = __SSAT(((q31_t) (((x << 16) >> 24) - ((y << 16) >> 24))), 8) << 8;
+ t = __SSAT(((q31_t) (((x << 8) >> 24) - ((y << 8) >> 24))), 8) << 16;
+ u = __SSAT(((q31_t) ((x >> 24) - (y >> 24))), 8) << 24;
+
+ sum =
+ (u & 0xFF000000) | (t & 0x00FF0000) | (s & 0x0000FF00) | (r & 0x000000FF);
+
+ return sum;
+ }
+
+ /*
+ * @brief C custom defined QADD16 for M3 and M0 processors
+ */
+
+ /*
+ * @brief C custom defined QADD16 for M3 and M0 processors
+ */
+ static __INLINE q31_t __QADD16(
+ q31_t x,
+ q31_t y)
+ {
+
+ q31_t sum;
+ q31_t r, s;
+
+ r = (short) x;
+ s = (short) y;
+
+ r = __SSAT(r + s, 16);
+ s = __SSAT(((q31_t) ((x >> 16) + (y >> 16))), 16) << 16;
+
+ sum = (s & 0xFFFF0000) | (r & 0x0000FFFF);
+
+ return sum;
+
+ }
+
+ /*
+ * @brief C custom defined SHADD16 for M3 and M0 processors
+ */
+ static __INLINE q31_t __SHADD16(
+ q31_t x,
+ q31_t y)
+ {
+
+ q31_t sum;
+ q31_t r, s;
+
+ r = (short) x;
+ s = (short) y;
+
+ r = ((r >> 1) + (s >> 1));
+ s = ((q31_t) ((x >> 17) + (y >> 17))) << 16;
+
+ sum = (s & 0xFFFF0000) | (r & 0x0000FFFF);
+
+ return sum;
+
+ }
+
+ /*
+ * @brief C custom defined QSUB16 for M3 and M0 processors
+ */
+ static __INLINE q31_t __QSUB16(
+ q31_t x,
+ q31_t y)
+ {
+
+ q31_t sum;
+ q31_t r, s;
+
+ r = (short) x;
+ s = (short) y;
+
+ r = __SSAT(r - s, 16);
+ s = __SSAT(((q31_t) ((x >> 16) - (y >> 16))), 16) << 16;
+
+ sum = (s & 0xFFFF0000) | (r & 0x0000FFFF);
+
+ return sum;
+ }
+
+ /*
+ * @brief C custom defined SHSUB16 for M3 and M0 processors
+ */
+ static __INLINE q31_t __SHSUB16(
+ q31_t x,
+ q31_t y)
+ {
+
+ q31_t diff;
+ q31_t r, s;
+
+ r = (short) x;
+ s = (short) y;
+
+ r = ((r >> 1) - (s >> 1));
+ s = (((x >> 17) - (y >> 17)) << 16);
+
+ diff = (s & 0xFFFF0000) | (r & 0x0000FFFF);
+
+ return diff;
+ }
+
+ /*
+ * @brief C custom defined QASX for M3 and M0 processors
+ */
+ static __INLINE q31_t __QASX(
+ q31_t x,
+ q31_t y)
+ {
+
+ q31_t sum = 0;
+
+ sum = ((sum + clip_q31_to_q15((q31_t) ((short) (x >> 16) + (short) y))) << 16) +
+ clip_q31_to_q15((q31_t) ((short) x - (short) (y >> 16)));
+
+ return sum;
+ }
+
+ /*
+ * @brief C custom defined SHASX for M3 and M0 processors
+ */
+ static __INLINE q31_t __SHASX(
+ q31_t x,
+ q31_t y)
+ {
+
+ q31_t sum;
+ q31_t r, s;
+
+ r = (short) x;
+ s = (short) y;
+
+ r = ((r >> 1) - (y >> 17));
+ s = (((x >> 17) + (s >> 1)) << 16);
+
+ sum = (s & 0xFFFF0000) | (r & 0x0000FFFF);
+
+ return sum;
+ }
+
+
+ /*
+ * @brief C custom defined QSAX for M3 and M0 processors
+ */
+ static __INLINE q31_t __QSAX(
+ q31_t x,
+ q31_t y)
+ {
+
+ q31_t sum = 0;
+
+ sum = ((sum + clip_q31_to_q15((q31_t) ((short) (x >> 16) - (short) y))) << 16) +
+ clip_q31_to_q15((q31_t) ((short) x + (short) (y >> 16)));
+
+ return sum;
+ }
+
+ /*
+ * @brief C custom defined SHSAX for M3 and M0 processors
+ */
+ static __INLINE q31_t __SHSAX(
+ q31_t x,
+ q31_t y)
+ {
+
+ q31_t sum;
+ q31_t r, s;
+
+ r = (short) x;
+ s = (short) y;
+
+ r = ((r >> 1) + (y >> 17));
+ s = (((x >> 17) - (s >> 1)) << 16);
+
+ sum = (s & 0xFFFF0000) | (r & 0x0000FFFF);
+
+ return sum;
+ }
+
+ /*
+ * @brief C custom defined SMUSDX for M3 and M0 processors
+ */
+ static __INLINE q31_t __SMUSDX(
+ q31_t x,
+ q31_t y)
+ {
+
+ return ((q31_t)(((short) x * (short) (y >> 16)) -
+ ((short) (x >> 16) * (short) y)));
+ }
+
+ /*
+ * @brief C custom defined SMUADX for M3 and M0 processors
+ */
+ static __INLINE q31_t __SMUADX(
+ q31_t x,
+ q31_t y)
+ {
+
+ return ((q31_t)(((short) x * (short) (y >> 16)) +
+ ((short) (x >> 16) * (short) y)));
+ }
+
+ /*
+ * @brief C custom defined QADD for M3 and M0 processors
+ */
+ static __INLINE q31_t __QADD(
+ q31_t x,
+ q31_t y)
+ {
+ return clip_q63_to_q31((q63_t) x + y);
+ }
+
+ /*
+ * @brief C custom defined QSUB for M3 and M0 processors
+ */
+ static __INLINE q31_t __QSUB(
+ q31_t x,
+ q31_t y)
+ {
+ return clip_q63_to_q31((q63_t) x - y);
+ }
+
+ /*
+ * @brief C custom defined SMLAD for M3 and M0 processors
+ */
+ static __INLINE q31_t __SMLAD(
+ q31_t x,
+ q31_t y,
+ q31_t sum)
+ {
+
+ return (sum + ((short) (x >> 16) * (short) (y >> 16)) +
+ ((short) x * (short) y));
+ }
+
+ /*
+ * @brief C custom defined SMLADX for M3 and M0 processors
+ */
+ static __INLINE q31_t __SMLADX(
+ q31_t x,
+ q31_t y,
+ q31_t sum)
+ {
+
+ return (sum + ((short) (x >> 16) * (short) (y)) +
+ ((short) x * (short) (y >> 16)));
+ }
+
+ /*
+ * @brief C custom defined SMLSDX for M3 and M0 processors
+ */
+ static __INLINE q31_t __SMLSDX(
+ q31_t x,
+ q31_t y,
+ q31_t sum)
+ {
+
+ return (sum - ((short) (x >> 16) * (short) (y)) +
+ ((short) x * (short) (y >> 16)));
+ }
+
+ /*
+ * @brief C custom defined SMLALD for M3 and M0 processors
+ */
+ static __INLINE q63_t __SMLALD(
+ q31_t x,
+ q31_t y,
+ q63_t sum)
+ {
+
+ return (sum + ((short) (x >> 16) * (short) (y >> 16)) +
+ ((short) x * (short) y));
+ }
+
+ /*
+ * @brief C custom defined SMLALDX for M3 and M0 processors
+ */
+ static __INLINE q63_t __SMLALDX(
+ q31_t x,
+ q31_t y,
+ q63_t sum)
+ {
+
+ return (sum + ((short) (x >> 16) * (short) y)) +
+ ((short) x * (short) (y >> 16));
+ }
+
+ /*
+ * @brief C custom defined SMUAD for M3 and M0 processors
+ */
+ static __INLINE q31_t __SMUAD(
+ q31_t x,
+ q31_t y)
+ {
+
+ return (((x >> 16) * (y >> 16)) +
+ (((x << 16) >> 16) * ((y << 16) >> 16)));
+ }
+
+ /*
+ * @brief C custom defined SMUSD for M3 and M0 processors
+ */
+ static __INLINE q31_t __SMUSD(
+ q31_t x,
+ q31_t y)
+ {
+
+ return (-((x >> 16) * (y >> 16)) +
+ (((x << 16) >> 16) * ((y << 16) >> 16)));
+ }
+
+
+
+
+#endif /* (ARM_MATH_CM3) || defined (ARM_MATH_CM0) */
+
+
+ /**
+ * @brief Instance structure for the Q7 FIR filter.
+ */
+ typedef struct
+ {
+ uint16_t numTaps; /**< number of filter coefficients in the filter. */
+ q7_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+ q7_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/
+ } arm_fir_instance_q7;
+
+ /**
+ * @brief Instance structure for the Q15 FIR filter.
+ */
+ typedef struct
+ {
+ uint16_t numTaps; /**< number of filter coefficients in the filter. */
+ q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+ q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/
+ } arm_fir_instance_q15;
+
+ /**
+ * @brief Instance structure for the Q31 FIR filter.
+ */
+ typedef struct
+ {
+ uint16_t numTaps; /**< number of filter coefficients in the filter. */
+ q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+ q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */
+ } arm_fir_instance_q31;
+
+ /**
+ * @brief Instance structure for the floating-point FIR filter.
+ */
+ typedef struct
+ {
+ uint16_t numTaps; /**< number of filter coefficients in the filter. */
+ float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+ float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */
+ } arm_fir_instance_f32;
+
+
+ /**
+ * @brief Processing function for the Q7 FIR filter.
+ * @param[in] *S points to an instance of the Q7 FIR filter structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ * @return none.
+ */
+ void arm_fir_q7(
+ const arm_fir_instance_q7 * S,
+ q7_t * pSrc,
+ q7_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for the Q7 FIR filter.
+ * @param[in,out] *S points to an instance of the Q7 FIR structure.
+ * @param[in] numTaps Number of filter coefficients in the filter.
+ * @param[in] *pCoeffs points to the filter coefficients.
+ * @param[in] *pState points to the state buffer.
+ * @param[in] blockSize number of samples that are processed.
+ * @return none
+ */
+ void arm_fir_init_q7(
+ arm_fir_instance_q7 * S,
+ uint16_t numTaps,
+ q7_t * pCoeffs,
+ q7_t * pState,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Processing function for the Q15 FIR filter.
+ * @param[in] *S points to an instance of the Q15 FIR structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ * @return none.
+ */
+ void arm_fir_q15(
+ const arm_fir_instance_q15 * S,
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Processing function for the fast Q15 FIR filter for Cortex-M3 and Cortex-M4.
+ * @param[in] *S points to an instance of the Q15 FIR filter structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ * @return none.
+ */
+ void arm_fir_fast_q15(
+ const arm_fir_instance_q15 * S,
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Initialization function for the Q15 FIR filter.
+ * @param[in,out] *S points to an instance of the Q15 FIR filter structure.
+ * @param[in] numTaps Number of filter coefficients in the filter. Must be even and greater than or equal to 4.
+ * @param[in] *pCoeffs points to the filter coefficients.
+ * @param[in] *pState points to the state buffer.
+ * @param[in] blockSize number of samples that are processed at a time.
+ * @return The function returns ARM_MATH_SUCCESS if initialization was successful or ARM_MATH_ARGUMENT_ERROR if
+ * numTaps is not a supported value.
+ */
+
+ arm_status arm_fir_init_q15(
+ arm_fir_instance_q15 * S,
+ uint16_t numTaps,
+ q15_t * pCoeffs,
+ q15_t * pState,
+ uint32_t blockSize);
+
+ /**
+ * @brief Processing function for the Q31 FIR filter.
+ * @param[in] *S points to an instance of the Q31 FIR filter structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ * @return none.
+ */
+ void arm_fir_q31(
+ const arm_fir_instance_q31 * S,
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Processing function for the fast Q31 FIR filter for Cortex-M3 and Cortex-M4.
+ * @param[in] *S points to an instance of the Q31 FIR structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ * @return none.
+ */
+ void arm_fir_fast_q31(
+ const arm_fir_instance_q31 * S,
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Initialization function for the Q31 FIR filter.
+ * @param[in,out] *S points to an instance of the Q31 FIR structure.
+ * @param[in] numTaps Number of filter coefficients in the filter.
+ * @param[in] *pCoeffs points to the filter coefficients.
+ * @param[in] *pState points to the state buffer.
+ * @param[in] blockSize number of samples that are processed at a time.
+ * @return none.
+ */
+ void arm_fir_init_q31(
+ arm_fir_instance_q31 * S,
+ uint16_t numTaps,
+ q31_t * pCoeffs,
+ q31_t * pState,
+ uint32_t blockSize);
+
+ /**
+ * @brief Processing function for the floating-point FIR filter.
+ * @param[in] *S points to an instance of the floating-point FIR structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ * @return none.
+ */
+ void arm_fir_f32(
+ const arm_fir_instance_f32 * S,
+ float32_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Initialization function for the floating-point FIR filter.
+ * @param[in,out] *S points to an instance of the floating-point FIR filter structure.
+ * @param[in] numTaps Number of filter coefficients in the filter.
+ * @param[in] *pCoeffs points to the filter coefficients.
+ * @param[in] *pState points to the state buffer.
+ * @param[in] blockSize number of samples that are processed at a time.
+ * @return none.
+ */
+ void arm_fir_init_f32(
+ arm_fir_instance_f32 * S,
+ uint16_t numTaps,
+ float32_t * pCoeffs,
+ float32_t * pState,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Instance structure for the Q15 Biquad cascade filter.
+ */
+ typedef struct
+ {
+ int8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */
+ q15_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */
+ q15_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */
+ int8_t postShift; /**< Additional shift, in bits, applied to each output sample. */
+
+ } arm_biquad_casd_df1_inst_q15;
+
+
+ /**
+ * @brief Instance structure for the Q31 Biquad cascade filter.
+ */
+ typedef struct
+ {
+ uint32_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */
+ q31_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */
+ q31_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */
+ uint8_t postShift; /**< Additional shift, in bits, applied to each output sample. */
+
+ } arm_biquad_casd_df1_inst_q31;
+
+ /**
+ * @brief Instance structure for the floating-point Biquad cascade filter.
+ */
+ typedef struct
+ {
+ uint32_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */
+ float32_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */
+ float32_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */
+
+
+ } arm_biquad_casd_df1_inst_f32;
+
+
+
+ /**
+ * @brief Processing function for the Q15 Biquad cascade filter.
+ * @param[in] *S points to an instance of the Q15 Biquad cascade structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ * @return none.
+ */
+
+ void arm_biquad_cascade_df1_q15(
+ const arm_biquad_casd_df1_inst_q15 * S,
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Initialization function for the Q15 Biquad cascade filter.
+ * @param[in,out] *S points to an instance of the Q15 Biquad cascade structure.
+ * @param[in] numStages number of 2nd order stages in the filter.
+ * @param[in] *pCoeffs points to the filter coefficients.
+ * @param[in] *pState points to the state buffer.
+ * @param[in] postShift Shift to be applied to the output. Varies according to the coefficients format
+ * @return none
+ */
+
+ void arm_biquad_cascade_df1_init_q15(
+ arm_biquad_casd_df1_inst_q15 * S,
+ uint8_t numStages,
+ q15_t * pCoeffs,
+ q15_t * pState,
+ int8_t postShift);
+
+
+ /**
+ * @brief Fast but less precise processing function for the Q15 Biquad cascade filter for Cortex-M3 and Cortex-M4.
+ * @param[in] *S points to an instance of the Q15 Biquad cascade structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ * @return none.
+ */
+
+ void arm_biquad_cascade_df1_fast_q15(
+ const arm_biquad_casd_df1_inst_q15 * S,
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Processing function for the Q31 Biquad cascade filter
+ * @param[in] *S points to an instance of the Q31 Biquad cascade structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ * @return none.
+ */
+
+ void arm_biquad_cascade_df1_q31(
+ const arm_biquad_casd_df1_inst_q31 * S,
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Fast but less precise processing function for the Q31 Biquad cascade filter for Cortex-M3 and Cortex-M4.
+ * @param[in] *S points to an instance of the Q31 Biquad cascade structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ * @return none.
+ */
+
+ void arm_biquad_cascade_df1_fast_q31(
+ const arm_biquad_casd_df1_inst_q31 * S,
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Initialization function for the Q31 Biquad cascade filter.
+ * @param[in,out] *S points to an instance of the Q31 Biquad cascade structure.
+ * @param[in] numStages number of 2nd order stages in the filter.
+ * @param[in] *pCoeffs points to the filter coefficients.
+ * @param[in] *pState points to the state buffer.
+ * @param[in] postShift Shift to be applied to the output. Varies according to the coefficients format
+ * @return none
+ */
+
+ void arm_biquad_cascade_df1_init_q31(
+ arm_biquad_casd_df1_inst_q31 * S,
+ uint8_t numStages,
+ q31_t * pCoeffs,
+ q31_t * pState,
+ int8_t postShift);
+
+ /**
+ * @brief Processing function for the floating-point Biquad cascade filter.
+ * @param[in] *S points to an instance of the floating-point Biquad cascade structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ * @return none.
+ */
+
+ void arm_biquad_cascade_df1_f32(
+ const arm_biquad_casd_df1_inst_f32 * S,
+ float32_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Initialization function for the floating-point Biquad cascade filter.
+ * @param[in,out] *S points to an instance of the floating-point Biquad cascade structure.
+ * @param[in] numStages number of 2nd order stages in the filter.
+ * @param[in] *pCoeffs points to the filter coefficients.
+ * @param[in] *pState points to the state buffer.
+ * @return none
+ */
+
+ void arm_biquad_cascade_df1_init_f32(
+ arm_biquad_casd_df1_inst_f32 * S,
+ uint8_t numStages,
+ float32_t * pCoeffs,
+ float32_t * pState);
+
+
+ /**
+ * @brief Instance structure for the floating-point matrix structure.
+ */
+
+ typedef struct
+ {
+ uint16_t numRows; /**< number of rows of the matrix. */
+ uint16_t numCols; /**< number of columns of the matrix. */
+ float32_t *pData; /**< points to the data of the matrix. */
+ } arm_matrix_instance_f32;
+
+ /**
+ * @brief Instance structure for the Q15 matrix structure.
+ */
+
+ typedef struct
+ {
+ uint16_t numRows; /**< number of rows of the matrix. */
+ uint16_t numCols; /**< number of columns of the matrix. */
+ q15_t *pData; /**< points to the data of the matrix. */
+
+ } arm_matrix_instance_q15;
+
+ /**
+ * @brief Instance structure for the Q31 matrix structure.
+ */
+
+ typedef struct
+ {
+ uint16_t numRows; /**< number of rows of the matrix. */
+ uint16_t numCols; /**< number of columns of the matrix. */
+ q31_t *pData; /**< points to the data of the matrix. */
+
+ } arm_matrix_instance_q31;
+
+
+
+ /**
+ * @brief Floating-point matrix addition.
+ * @param[in] *pSrcA points to the first input matrix structure
+ * @param[in] *pSrcB points to the second input matrix structure
+ * @param[out] *pDst points to output matrix structure
+ * @return The function returns either
+ * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking.
+ */
+
+ arm_status arm_mat_add_f32(
+ const arm_matrix_instance_f32 * pSrcA,
+ const arm_matrix_instance_f32 * pSrcB,
+ arm_matrix_instance_f32 * pDst);
+
+ /**
+ * @brief Q15 matrix addition.
+ * @param[in] *pSrcA points to the first input matrix structure
+ * @param[in] *pSrcB points to the second input matrix structure
+ * @param[out] *pDst points to output matrix structure
+ * @return The function returns either
+ * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking.
+ */
+
+ arm_status arm_mat_add_q15(
+ const arm_matrix_instance_q15 * pSrcA,
+ const arm_matrix_instance_q15 * pSrcB,
+ arm_matrix_instance_q15 * pDst);
+
+ /**
+ * @brief Q31 matrix addition.
+ * @param[in] *pSrcA points to the first input matrix structure
+ * @param[in] *pSrcB points to the second input matrix structure
+ * @param[out] *pDst points to output matrix structure
+ * @return The function returns either
+ * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking.
+ */
+
+ arm_status arm_mat_add_q31(
+ const arm_matrix_instance_q31 * pSrcA,
+ const arm_matrix_instance_q31 * pSrcB,
+ arm_matrix_instance_q31 * pDst);
+
+
+ /**
+ * @brief Floating-point matrix transpose.
+ * @param[in] *pSrc points to the input matrix
+ * @param[out] *pDst points to the output matrix
+ * @return The function returns either ARM_MATH_SIZE_MISMATCH
+ * or ARM_MATH_SUCCESS based on the outcome of size checking.
+ */
+
+ arm_status arm_mat_trans_f32(
+ const arm_matrix_instance_f32 * pSrc,
+ arm_matrix_instance_f32 * pDst);
+
+
+ /**
+ * @brief Q15 matrix transpose.
+ * @param[in] *pSrc points to the input matrix
+ * @param[out] *pDst points to the output matrix
+ * @return The function returns either ARM_MATH_SIZE_MISMATCH
+ * or ARM_MATH_SUCCESS based on the outcome of size checking.
+ */
+
+ arm_status arm_mat_trans_q15(
+ const arm_matrix_instance_q15 * pSrc,
+ arm_matrix_instance_q15 * pDst);
+
+ /**
+ * @brief Q31 matrix transpose.
+ * @param[in] *pSrc points to the input matrix
+ * @param[out] *pDst points to the output matrix
+ * @return The function returns either ARM_MATH_SIZE_MISMATCH
+ * or ARM_MATH_SUCCESS based on the outcome of size checking.
+ */
+
+ arm_status arm_mat_trans_q31(
+ const arm_matrix_instance_q31 * pSrc,
+ arm_matrix_instance_q31 * pDst);
+
+
+ /**
+ * @brief Floating-point matrix multiplication
+ * @param[in] *pSrcA points to the first input matrix structure
+ * @param[in] *pSrcB points to the second input matrix structure
+ * @param[out] *pDst points to output matrix structure
+ * @return The function returns either
+ * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking.
+ */
+
+ arm_status arm_mat_mult_f32(
+ const arm_matrix_instance_f32 * pSrcA,
+ const arm_matrix_instance_f32 * pSrcB,
+ arm_matrix_instance_f32 * pDst);
+
+ /**
+ * @brief Q15 matrix multiplication
+ * @param[in] *pSrcA points to the first input matrix structure
+ * @param[in] *pSrcB points to the second input matrix structure
+ * @param[out] *pDst points to output matrix structure
+ * @return The function returns either
+ * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking.
+ */
+
+ arm_status arm_mat_mult_q15(
+ const arm_matrix_instance_q15 * pSrcA,
+ const arm_matrix_instance_q15 * pSrcB,
+ arm_matrix_instance_q15 * pDst,
+ q15_t * pState);
+
+ /**
+ * @brief Q15 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4
+ * @param[in] *pSrcA points to the first input matrix structure
+ * @param[in] *pSrcB points to the second input matrix structure
+ * @param[out] *pDst points to output matrix structure
+ * @param[in] *pState points to the array for storing intermediate results
+ * @return The function returns either
+ * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking.
+ */
+
+ arm_status arm_mat_mult_fast_q15(
+ const arm_matrix_instance_q15 * pSrcA,
+ const arm_matrix_instance_q15 * pSrcB,
+ arm_matrix_instance_q15 * pDst,
+ q15_t * pState);
+
+ /**
+ * @brief Q31 matrix multiplication
+ * @param[in] *pSrcA points to the first input matrix structure
+ * @param[in] *pSrcB points to the second input matrix structure
+ * @param[out] *pDst points to output matrix structure
+ * @return The function returns either
+ * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking.
+ */
+
+ arm_status arm_mat_mult_q31(
+ const arm_matrix_instance_q31 * pSrcA,
+ const arm_matrix_instance_q31 * pSrcB,
+ arm_matrix_instance_q31 * pDst);
+
+ /**
+ * @brief Q31 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4
+ * @param[in] *pSrcA points to the first input matrix structure
+ * @param[in] *pSrcB points to the second input matrix structure
+ * @param[out] *pDst points to output matrix structure
+ * @return The function returns either
+ * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking.
+ */
+
+ arm_status arm_mat_mult_fast_q31(
+ const arm_matrix_instance_q31 * pSrcA,
+ const arm_matrix_instance_q31 * pSrcB,
+ arm_matrix_instance_q31 * pDst);
+
+
+ /**
+ * @brief Floating-point matrix subtraction
+ * @param[in] *pSrcA points to the first input matrix structure
+ * @param[in] *pSrcB points to the second input matrix structure
+ * @param[out] *pDst points to output matrix structure
+ * @return The function returns either
+ * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking.
+ */
+
+ arm_status arm_mat_sub_f32(
+ const arm_matrix_instance_f32 * pSrcA,
+ const arm_matrix_instance_f32 * pSrcB,
+ arm_matrix_instance_f32 * pDst);
+
+ /**
+ * @brief Q15 matrix subtraction
+ * @param[in] *pSrcA points to the first input matrix structure
+ * @param[in] *pSrcB points to the second input matrix structure
+ * @param[out] *pDst points to output matrix structure
+ * @return The function returns either
+ * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking.
+ */
+
+ arm_status arm_mat_sub_q15(
+ const arm_matrix_instance_q15 * pSrcA,
+ const arm_matrix_instance_q15 * pSrcB,
+ arm_matrix_instance_q15 * pDst);
+
+ /**
+ * @brief Q31 matrix subtraction
+ * @param[in] *pSrcA points to the first input matrix structure
+ * @param[in] *pSrcB points to the second input matrix structure
+ * @param[out] *pDst points to output matrix structure
+ * @return The function returns either
+ * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking.
+ */
+
+ arm_status arm_mat_sub_q31(
+ const arm_matrix_instance_q31 * pSrcA,
+ const arm_matrix_instance_q31 * pSrcB,
+ arm_matrix_instance_q31 * pDst);
+
+ /**
+ * @brief Floating-point matrix scaling.
+ * @param[in] *pSrc points to the input matrix
+ * @param[in] scale scale factor
+ * @param[out] *pDst points to the output matrix
+ * @return The function returns either
+ * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking.
+ */
+
+ arm_status arm_mat_scale_f32(
+ const arm_matrix_instance_f32 * pSrc,
+ float32_t scale,
+ arm_matrix_instance_f32 * pDst);
+
+ /**
+ * @brief Q15 matrix scaling.
+ * @param[in] *pSrc points to input matrix
+ * @param[in] scaleFract fractional portion of the scale factor
+ * @param[in] shift number of bits to shift the result by
+ * @param[out] *pDst points to output matrix
+ * @return The function returns either
+ * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking.
+ */
+
+ arm_status arm_mat_scale_q15(
+ const arm_matrix_instance_q15 * pSrc,
+ q15_t scaleFract,
+ int32_t shift,
+ arm_matrix_instance_q15 * pDst);
+
+ /**
+ * @brief Q31 matrix scaling.
+ * @param[in] *pSrc points to input matrix
+ * @param[in] scaleFract fractional portion of the scale factor
+ * @param[in] shift number of bits to shift the result by
+ * @param[out] *pDst points to output matrix structure
+ * @return The function returns either
+ * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking.
+ */
+
+ arm_status arm_mat_scale_q31(
+ const arm_matrix_instance_q31 * pSrc,
+ q31_t scaleFract,
+ int32_t shift,
+ arm_matrix_instance_q31 * pDst);
+
+
+ /**
+ * @brief Q31 matrix initialization.
+ * @param[in,out] *S points to an instance of the floating-point matrix structure.
+ * @param[in] nRows number of rows in the matrix.
+ * @param[in] nColumns number of columns in the matrix.
+ * @param[in] *pData points to the matrix data array.
+ * @return none
+ */
+
+ void arm_mat_init_q31(
+ arm_matrix_instance_q31 * S,
+ uint16_t nRows,
+ uint16_t nColumns,
+ q31_t *pData);
+
+ /**
+ * @brief Q15 matrix initialization.
+ * @param[in,out] *S points to an instance of the floating-point matrix structure.
+ * @param[in] nRows number of rows in the matrix.
+ * @param[in] nColumns number of columns in the matrix.
+ * @param[in] *pData points to the matrix data array.
+ * @return none
+ */
+
+ void arm_mat_init_q15(
+ arm_matrix_instance_q15 * S,
+ uint16_t nRows,
+ uint16_t nColumns,
+ q15_t *pData);
+
+ /**
+ * @brief Floating-point matrix initialization.
+ * @param[in,out] *S points to an instance of the floating-point matrix structure.
+ * @param[in] nRows number of rows in the matrix.
+ * @param[in] nColumns number of columns in the matrix.
+ * @param[in] *pData points to the matrix data array.
+ * @return none
+ */
+
+ void arm_mat_init_f32(
+ arm_matrix_instance_f32 * S,
+ uint16_t nRows,
+ uint16_t nColumns,
+ float32_t *pData);
+
+
+
+ /**
+ * @brief Instance structure for the Q15 PID Control.
+ */
+ typedef struct
+ {
+ q15_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */
+ #ifdef ARM_MATH_CM0
+ q15_t A1;
+ q15_t A2;
+ #else
+ q31_t A1; /**< The derived gain A1 = -Kp - 2Kd | Kd.*/
+ #endif
+ q15_t state[3]; /**< The state array of length 3. */
+ q15_t Kp; /**< The proportional gain. */
+ q15_t Ki; /**< The integral gain. */
+ q15_t Kd; /**< The derivative gain. */
+ } arm_pid_instance_q15;
+
+ /**
+ * @brief Instance structure for the Q31 PID Control.
+ */
+ typedef struct
+ {
+ q31_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */
+ q31_t A1; /**< The derived gain, A1 = -Kp - 2Kd. */
+ q31_t A2; /**< The derived gain, A2 = Kd . */
+ q31_t state[3]; /**< The state array of length 3. */
+ q31_t Kp; /**< The proportional gain. */
+ q31_t Ki; /**< The integral gain. */
+ q31_t Kd; /**< The derivative gain. */
+
+ } arm_pid_instance_q31;
+
+ /**
+ * @brief Instance structure for the floating-point PID Control.
+ */
+ typedef struct
+ {
+ float32_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */
+ float32_t A1; /**< The derived gain, A1 = -Kp - 2Kd. */
+ float32_t A2; /**< The derived gain, A2 = Kd . */
+ float32_t state[3]; /**< The state array of length 3. */
+ float32_t Kp; /**< The proportional gain. */
+ float32_t Ki; /**< The integral gain. */
+ float32_t Kd; /**< The derivative gain. */
+ } arm_pid_instance_f32;
+
+
+
+ /**
+ * @brief Initialization function for the floating-point PID Control.
+ * @param[in,out] *S points to an instance of the PID structure.
+ * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state.
+ * @return none.
+ */
+ void arm_pid_init_f32(
+ arm_pid_instance_f32 * S,
+ int32_t resetStateFlag);
+
+ /**
+ * @brief Reset function for the floating-point PID Control.
+ * @param[in,out] *S is an instance of the floating-point PID Control structure
+ * @return none
+ */
+ void arm_pid_reset_f32(
+ arm_pid_instance_f32 * S);
+
+
+ /**
+ * @brief Initialization function for the Q31 PID Control.
+ * @param[in,out] *S points to an instance of the Q15 PID structure.
+ * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state.
+ * @return none.
+ */
+ void arm_pid_init_q31(
+ arm_pid_instance_q31 * S,
+ int32_t resetStateFlag);
+
+
+ /**
+ * @brief Reset function for the Q31 PID Control.
+ * @param[in,out] *S points to an instance of the Q31 PID Control structure
+ * @return none
+ */
+
+ void arm_pid_reset_q31(
+ arm_pid_instance_q31 * S);
+
+ /**
+ * @brief Initialization function for the Q15 PID Control.
+ * @param[in,out] *S points to an instance of the Q15 PID structure.
+ * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state.
+ * @return none.
+ */
+ void arm_pid_init_q15(
+ arm_pid_instance_q15 * S,
+ int32_t resetStateFlag);
+
+ /**
+ * @brief Reset function for the Q15 PID Control.
+ * @param[in,out] *S points to an instance of the q15 PID Control structure
+ * @return none
+ */
+ void arm_pid_reset_q15(
+ arm_pid_instance_q15 * S);
+
+
+ /**
+ * @brief Instance structure for the floating-point Linear Interpolate function.
+ */
+ typedef struct
+ {
+ uint32_t nValues;
+ float32_t x1;
+ float32_t xSpacing;
+ float32_t *pYData; /**< pointer to the table of Y values */
+ } arm_linear_interp_instance_f32;
+
+ /**
+ * @brief Instance structure for the floating-point bilinear interpolation function.
+ */
+
+ typedef struct
+ {
+ uint16_t numRows; /**< number of rows in the data table. */
+ uint16_t numCols; /**< number of columns in the data table. */
+ float32_t *pData; /**< points to the data table. */
+ } arm_bilinear_interp_instance_f32;
+
+ /**
+ * @brief Instance structure for the Q31 bilinear interpolation function.
+ */
+
+ typedef struct
+ {
+ uint16_t numRows; /**< number of rows in the data table. */
+ uint16_t numCols; /**< number of columns in the data table. */
+ q31_t *pData; /**< points to the data table. */
+ } arm_bilinear_interp_instance_q31;
+
+ /**
+ * @brief Instance structure for the Q15 bilinear interpolation function.
+ */
+
+ typedef struct
+ {
+ uint16_t numRows; /**< number of rows in the data table. */
+ uint16_t numCols; /**< number of columns in the data table. */
+ q15_t *pData; /**< points to the data table. */
+ } arm_bilinear_interp_instance_q15;
+
+ /**
+ * @brief Instance structure for the Q15 bilinear interpolation function.
+ */
+
+ typedef struct
+ {
+ uint16_t numRows; /**< number of rows in the data table. */
+ uint16_t numCols; /**< number of columns in the data table. */
+ q7_t *pData; /**< points to the data table. */
+ } arm_bilinear_interp_instance_q7;
+
+
+ /**
+ * @brief Q7 vector multiplication.
+ * @param[in] *pSrcA points to the first input vector
+ * @param[in] *pSrcB points to the second input vector
+ * @param[out] *pDst points to the output vector
+ * @param[in] blockSize number of samples in each vector
+ * @return none.
+ */
+
+ void arm_mult_q7(
+ q7_t * pSrcA,
+ q7_t * pSrcB,
+ q7_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Q15 vector multiplication.
+ * @param[in] *pSrcA points to the first input vector
+ * @param[in] *pSrcB points to the second input vector
+ * @param[out] *pDst points to the output vector
+ * @param[in] blockSize number of samples in each vector
+ * @return none.
+ */
+
+ void arm_mult_q15(
+ q15_t * pSrcA,
+ q15_t * pSrcB,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Q31 vector multiplication.
+ * @param[in] *pSrcA points to the first input vector
+ * @param[in] *pSrcB points to the second input vector
+ * @param[out] *pDst points to the output vector
+ * @param[in] blockSize number of samples in each vector
+ * @return none.
+ */
+
+ void arm_mult_q31(
+ q31_t * pSrcA,
+ q31_t * pSrcB,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Floating-point vector multiplication.
+ * @param[in] *pSrcA points to the first input vector
+ * @param[in] *pSrcB points to the second input vector
+ * @param[out] *pDst points to the output vector
+ * @param[in] blockSize number of samples in each vector
+ * @return none.
+ */
+
+ void arm_mult_f32(
+ float32_t * pSrcA,
+ float32_t * pSrcB,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Instance structure for the Q15 CFFT/CIFFT function.
+ */
+
+ typedef struct
+ {
+ uint16_t fftLen; /**< length of the FFT. */
+ uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */
+ uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */
+ q15_t *pTwiddle; /**< points to the twiddle factor table. */
+ uint16_t *pBitRevTable; /**< points to the bit reversal table. */
+ uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+ uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */
+ } arm_cfft_radix4_instance_q15;
+
+ /**
+ * @brief Instance structure for the Q31 CFFT/CIFFT function.
+ */
+
+ typedef struct
+ {
+ uint16_t fftLen; /**< length of the FFT. */
+ uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */
+ uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */
+ q31_t *pTwiddle; /**< points to the twiddle factor table. */
+ uint16_t *pBitRevTable; /**< points to the bit reversal table. */
+ uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+ uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */
+ } arm_cfft_radix4_instance_q31;
+
+ /**
+ * @brief Instance structure for the floating-point CFFT/CIFFT function.
+ */
+
+ typedef struct
+ {
+ uint16_t fftLen; /**< length of the FFT. */
+ uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */
+ uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */
+ float32_t *pTwiddle; /**< points to the twiddle factor table. */
+ uint16_t *pBitRevTable; /**< points to the bit reversal table. */
+ uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+ uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */
+ float32_t onebyfftLen; /**< value of 1/fftLen. */
+ } arm_cfft_radix4_instance_f32;
+
+ /**
+ * @brief Processing function for the Q15 CFFT/CIFFT.
+ * @param[in] *S points to an instance of the Q15 CFFT/CIFFT structure.
+ * @param[in, out] *pSrc points to the complex data buffer. Processing occurs in-place.
+ * @return none.
+ */
+
+ void arm_cfft_radix4_q15(
+ const arm_cfft_radix4_instance_q15 * S,
+ q15_t * pSrc);
+
+ /**
+ * @brief Initialization function for the Q15 CFFT/CIFFT.
+ * @param[in,out] *S points to an instance of the Q15 CFFT/CIFFT structure.
+ * @param[in] fftLen length of the FFT.
+ * @param[in] ifftFlag flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform.
+ * @param[in] bitReverseFlag flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output.
+ * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLen is not a supported value.
+ */
+
+ arm_status arm_cfft_radix4_init_q15(
+ arm_cfft_radix4_instance_q15 * S,
+ uint16_t fftLen,
+ uint8_t ifftFlag,
+ uint8_t bitReverseFlag);
+
+ /**
+ * @brief Processing function for the Q31 CFFT/CIFFT.
+ * @param[in] *S points to an instance of the Q31 CFFT/CIFFT structure.
+ * @param[in, out] *pSrc points to the complex data buffer. Processing occurs in-place.
+ * @return none.
+ */
+
+ void arm_cfft_radix4_q31(
+ const arm_cfft_radix4_instance_q31 * S,
+ q31_t * pSrc);
+
+ /**
+ * @brief Initialization function for the Q31 CFFT/CIFFT.
+ * @param[in,out] *S points to an instance of the Q31 CFFT/CIFFT structure.
+ * @param[in] fftLen length of the FFT.
+ * @param[in] ifftFlag flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform.
+ * @param[in] bitReverseFlag flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output.
+ * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLen is not a supported value.
+ */
+
+ arm_status arm_cfft_radix4_init_q31(
+ arm_cfft_radix4_instance_q31 * S,
+ uint16_t fftLen,
+ uint8_t ifftFlag,
+ uint8_t bitReverseFlag);
+
+ /**
+ * @brief Processing function for the floating-point CFFT/CIFFT.
+ * @param[in] *S points to an instance of the floating-point CFFT/CIFFT structure.
+ * @param[in, out] *pSrc points to the complex data buffer. Processing occurs in-place.
+ * @return none.
+ */
+
+ void arm_cfft_radix4_f32(
+ const arm_cfft_radix4_instance_f32 * S,
+ float32_t * pSrc);
+
+ /**
+ * @brief Initialization function for the floating-point CFFT/CIFFT.
+ * @param[in,out] *S points to an instance of the floating-point CFFT/CIFFT structure.
+ * @param[in] fftLen length of the FFT.
+ * @param[in] ifftFlag flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform.
+ * @param[in] bitReverseFlag flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output.
+ * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLen is not a supported value.
+ */
+
+ arm_status arm_cfft_radix4_init_f32(
+ arm_cfft_radix4_instance_f32 * S,
+ uint16_t fftLen,
+ uint8_t ifftFlag,
+ uint8_t bitReverseFlag);
+
+
+
+ /*----------------------------------------------------------------------
+ * Internal functions prototypes FFT function
+ ----------------------------------------------------------------------*/
+
+ /**
+ * @brief Core function for the floating-point CFFT butterfly process.
+ * @param[in, out] *pSrc points to the in-place buffer of floating-point data type.
+ * @param[in] fftLen length of the FFT.
+ * @param[in] *pCoef points to the twiddle coefficient buffer.
+ * @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table.
+ * @return none.
+ */
+
+ void arm_radix4_butterfly_f32(
+ float32_t * pSrc,
+ uint16_t fftLen,
+ float32_t * pCoef,
+ uint16_t twidCoefModifier);
+
+ /**
+ * @brief Core function for the floating-point CIFFT butterfly process.
+ * @param[in, out] *pSrc points to the in-place buffer of floating-point data type.
+ * @param[in] fftLen length of the FFT.
+ * @param[in] *pCoef points to twiddle coefficient buffer.
+ * @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table.
+ * @param[in] onebyfftLen value of 1/fftLen.
+ * @return none.
+ */
+
+ void arm_radix4_butterfly_inverse_f32(
+ float32_t * pSrc,
+ uint16_t fftLen,
+ float32_t * pCoef,
+ uint16_t twidCoefModifier,
+ float32_t onebyfftLen);
+
+ /**
+ * @brief In-place bit reversal function.
+ * @param[in, out] *pSrc points to the in-place buffer of floating-point data type.
+ * @param[in] fftSize length of the FFT.
+ * @param[in] bitRevFactor bit reversal modifier that supports different size FFTs with the same bit reversal table.
+ * @param[in] *pBitRevTab points to the bit reversal table.
+ * @return none.
+ */
+
+ void arm_bitreversal_f32(
+ float32_t *pSrc,
+ uint16_t fftSize,
+ uint16_t bitRevFactor,
+ uint16_t *pBitRevTab);
+
+ /**
+ * @brief Core function for the Q31 CFFT butterfly process.
+ * @param[in, out] *pSrc points to the in-place buffer of Q31 data type.
+ * @param[in] fftLen length of the FFT.
+ * @param[in] *pCoef points to twiddle coefficient buffer.
+ * @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table.
+ * @return none.
+ */
+
+ void arm_radix4_butterfly_q31(
+ q31_t *pSrc,
+ uint32_t fftLen,
+ q31_t *pCoef,
+ uint32_t twidCoefModifier);
+
+ /**
+ * @brief Core function for the Q31 CIFFT butterfly process.
+ * @param[in, out] *pSrc points to the in-place buffer of Q31 data type.
+ * @param[in] fftLen length of the FFT.
+ * @param[in] *pCoef points to twiddle coefficient buffer.
+ * @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table.
+ * @return none.
+ */
+
+ void arm_radix4_butterfly_inverse_q31(
+ q31_t * pSrc,
+ uint32_t fftLen,
+ q31_t * pCoef,
+ uint32_t twidCoefModifier);
+
+ /**
+ * @brief In-place bit reversal function.
+ * @param[in, out] *pSrc points to the in-place buffer of Q31 data type.
+ * @param[in] fftLen length of the FFT.
+ * @param[in] bitRevFactor bit reversal modifier that supports different size FFTs with the same bit reversal table
+ * @param[in] *pBitRevTab points to bit reversal table.
+ * @return none.
+ */
+
+ void arm_bitreversal_q31(
+ q31_t * pSrc,
+ uint32_t fftLen,
+ uint16_t bitRevFactor,
+ uint16_t *pBitRevTab);
+
+ /**
+ * @brief Core function for the Q15 CFFT butterfly process.
+ * @param[in, out] *pSrc16 points to the in-place buffer of Q15 data type.
+ * @param[in] fftLen length of the FFT.
+ * @param[in] *pCoef16 points to twiddle coefficient buffer.
+ * @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table.
+ * @return none.
+ */
+
+ void arm_radix4_butterfly_q15(
+ q15_t *pSrc16,
+ uint32_t fftLen,
+ q15_t *pCoef16,
+ uint32_t twidCoefModifier);
+
+ /**
+ * @brief Core function for the Q15 CIFFT butterfly process.
+ * @param[in, out] *pSrc16 points to the in-place buffer of Q15 data type.
+ * @param[in] fftLen length of the FFT.
+ * @param[in] *pCoef16 points to twiddle coefficient buffer.
+ * @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table.
+ * @return none.
+ */
+
+ void arm_radix4_butterfly_inverse_q15(
+ q15_t *pSrc16,
+ uint32_t fftLen,
+ q15_t *pCoef16,
+ uint32_t twidCoefModifier);
+
+ /**
+ * @brief In-place bit reversal function.
+ * @param[in, out] *pSrc points to the in-place buffer of Q15 data type.
+ * @param[in] fftLen length of the FFT.
+ * @param[in] bitRevFactor bit reversal modifier that supports different size FFTs with the same bit reversal table
+ * @param[in] *pBitRevTab points to bit reversal table.
+ * @return none.
+ */
+
+ void arm_bitreversal_q15(
+ q15_t * pSrc,
+ uint32_t fftLen,
+ uint16_t bitRevFactor,
+ uint16_t *pBitRevTab);
+
+ /**
+ * @brief Instance structure for the Q15 RFFT/RIFFT function.
+ */
+
+ typedef struct
+ {
+ uint32_t fftLenReal; /**< length of the real FFT. */
+ uint32_t fftLenBy2; /**< length of the complex FFT. */
+ uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */
+ uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */
+ uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+ q15_t *pTwiddleAReal; /**< points to the real twiddle factor table. */
+ q15_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */
+ arm_cfft_radix4_instance_q15 *pCfft; /**< points to the complex FFT instance. */
+ } arm_rfft_instance_q15;
+
+ /**
+ * @brief Instance structure for the Q31 RFFT/RIFFT function.
+ */
+
+ typedef struct
+ {
+ uint32_t fftLenReal; /**< length of the real FFT. */
+ uint32_t fftLenBy2; /**< length of the complex FFT. */
+ uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */
+ uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */
+ uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+ q31_t *pTwiddleAReal; /**< points to the real twiddle factor table. */
+ q31_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */
+ arm_cfft_radix4_instance_q31 *pCfft; /**< points to the complex FFT instance. */
+ } arm_rfft_instance_q31;
+
+ /**
+ * @brief Instance structure for the floating-point RFFT/RIFFT function.
+ */
+
+ typedef struct
+ {
+ uint32_t fftLenReal; /**< length of the real FFT. */
+ uint16_t fftLenBy2; /**< length of the complex FFT. */
+ uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */
+ uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */
+ uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+ float32_t *pTwiddleAReal; /**< points to the real twiddle factor table. */
+ float32_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */
+ arm_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */
+ } arm_rfft_instance_f32;
+
+ /**
+ * @brief Processing function for the Q15 RFFT/RIFFT.
+ * @param[in] *S points to an instance of the Q15 RFFT/RIFFT structure.
+ * @param[in] *pSrc points to the input buffer.
+ * @param[out] *pDst points to the output buffer.
+ * @return none.
+ */
+
+ void arm_rfft_q15(
+ const arm_rfft_instance_q15 * S,
+ q15_t * pSrc,
+ q15_t * pDst);
+
+ /**
+ * @brief Initialization function for the Q15 RFFT/RIFFT.
+ * @param[in, out] *S points to an instance of the Q15 RFFT/RIFFT structure.
+ * @param[in] *S_CFFT points to an instance of the Q15 CFFT/CIFFT structure.
+ * @param[in] fftLenReal length of the FFT.
+ * @param[in] ifftFlagR flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform.
+ * @param[in] bitReverseFlag flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output.
+ * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLenReal is not a supported value.
+ */
+
+ arm_status arm_rfft_init_q15(
+ arm_rfft_instance_q15 * S,
+ arm_cfft_radix4_instance_q15 * S_CFFT,
+ uint32_t fftLenReal,
+ uint32_t ifftFlagR,
+ uint32_t bitReverseFlag);
+
+ /**
+ * @brief Processing function for the Q31 RFFT/RIFFT.
+ * @param[in] *S points to an instance of the Q31 RFFT/RIFFT structure.
+ * @param[in] *pSrc points to the input buffer.
+ * @param[out] *pDst points to the output buffer.
+ * @return none.
+ */
+
+ void arm_rfft_q31(
+ const arm_rfft_instance_q31 * S,
+ q31_t * pSrc,
+ q31_t * pDst);
+
+ /**
+ * @brief Initialization function for the Q31 RFFT/RIFFT.
+ * @param[in, out] *S points to an instance of the Q31 RFFT/RIFFT structure.
+ * @param[in, out] *S_CFFT points to an instance of the Q31 CFFT/CIFFT structure.
+ * @param[in] fftLenReal length of the FFT.
+ * @param[in] ifftFlagR flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform.
+ * @param[in] bitReverseFlag flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output.
+ * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLenReal is not a supported value.
+ */
+
+ arm_status arm_rfft_init_q31(
+ arm_rfft_instance_q31 * S,
+ arm_cfft_radix4_instance_q31 * S_CFFT,
+ uint32_t fftLenReal,
+ uint32_t ifftFlagR,
+ uint32_t bitReverseFlag);
+
+ /**
+ * @brief Initialization function for the floating-point RFFT/RIFFT.
+ * @param[in,out] *S points to an instance of the floating-point RFFT/RIFFT structure.
+ * @param[in,out] *S_CFFT points to an instance of the floating-point CFFT/CIFFT structure.
+ * @param[in] fftLenReal length of the FFT.
+ * @param[in] ifftFlagR flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform.
+ * @param[in] bitReverseFlag flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output.
+ * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLenReal is not a supported value.
+ */
+
+ arm_status arm_rfft_init_f32(
+ arm_rfft_instance_f32 * S,
+ arm_cfft_radix4_instance_f32 * S_CFFT,
+ uint32_t fftLenReal,
+ uint32_t ifftFlagR,
+ uint32_t bitReverseFlag);
+
+ /**
+ * @brief Processing function for the floating-point RFFT/RIFFT.
+ * @param[in] *S points to an instance of the floating-point RFFT/RIFFT structure.
+ * @param[in] *pSrc points to the input buffer.
+ * @param[out] *pDst points to the output buffer.
+ * @return none.
+ */
+
+ void arm_rfft_f32(
+ const arm_rfft_instance_f32 * S,
+ float32_t * pSrc,
+ float32_t * pDst);
+
+ /**
+ * @brief Instance structure for the floating-point DCT4/IDCT4 function.
+ */
+
+ typedef struct
+ {
+ uint16_t N; /**< length of the DCT4. */
+ uint16_t Nby2; /**< half of the length of the DCT4. */
+ float32_t normalize; /**< normalizing factor. */
+ float32_t *pTwiddle; /**< points to the twiddle factor table. */
+ float32_t *pCosFactor; /**< points to the cosFactor table. */
+ arm_rfft_instance_f32 *pRfft; /**< points to the real FFT instance. */
+ arm_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */
+ } arm_dct4_instance_f32;
+
+ /**
+ * @brief Initialization function for the floating-point DCT4/IDCT4.
+ * @param[in,out] *S points to an instance of floating-point DCT4/IDCT4 structure.
+ * @param[in] *S_RFFT points to an instance of floating-point RFFT/RIFFT structure.
+ * @param[in] *S_CFFT points to an instance of floating-point CFFT/CIFFT structure.
+ * @param[in] N length of the DCT4.
+ * @param[in] Nby2 half of the length of the DCT4.
+ * @param[in] normalize normalizing factor.
+ * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLenReal is not a supported transform length.
+ */
+
+ arm_status arm_dct4_init_f32(
+ arm_dct4_instance_f32 * S,
+ arm_rfft_instance_f32 * S_RFFT,
+ arm_cfft_radix4_instance_f32 * S_CFFT,
+ uint16_t N,
+ uint16_t Nby2,
+ float32_t normalize);
+
+ /**
+ * @brief Processing function for the floating-point DCT4/IDCT4.
+ * @param[in] *S points to an instance of the floating-point DCT4/IDCT4 structure.
+ * @param[in] *pState points to state buffer.
+ * @param[in,out] *pInlineBuffer points to the in-place input and output buffer.
+ * @return none.
+ */
+
+ void arm_dct4_f32(
+ const arm_dct4_instance_f32 * S,
+ float32_t * pState,
+ float32_t * pInlineBuffer);
+
+ /**
+ * @brief Instance structure for the Q31 DCT4/IDCT4 function.
+ */
+
+ typedef struct
+ {
+ uint16_t N; /**< length of the DCT4. */
+ uint16_t Nby2; /**< half of the length of the DCT4. */
+ q31_t normalize; /**< normalizing factor. */
+ q31_t *pTwiddle; /**< points to the twiddle factor table. */
+ q31_t *pCosFactor; /**< points to the cosFactor table. */
+ arm_rfft_instance_q31 *pRfft; /**< points to the real FFT instance. */
+ arm_cfft_radix4_instance_q31 *pCfft; /**< points to the complex FFT instance. */
+ } arm_dct4_instance_q31;
+
+ /**
+ * @brief Initialization function for the Q31 DCT4/IDCT4.
+ * @param[in,out] *S points to an instance of Q31 DCT4/IDCT4 structure.
+ * @param[in] *S_RFFT points to an instance of Q31 RFFT/RIFFT structure
+ * @param[in] *S_CFFT points to an instance of Q31 CFFT/CIFFT structure
+ * @param[in] N length of the DCT4.
+ * @param[in] Nby2 half of the length of the DCT4.
+ * @param[in] normalize normalizing factor.
+ * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if N is not a supported transform length.
+ */
+
+ arm_status arm_dct4_init_q31(
+ arm_dct4_instance_q31 * S,
+ arm_rfft_instance_q31 * S_RFFT,
+ arm_cfft_radix4_instance_q31 * S_CFFT,
+ uint16_t N,
+ uint16_t Nby2,
+ q31_t normalize);
+
+ /**
+ * @brief Processing function for the Q31 DCT4/IDCT4.
+ * @param[in] *S points to an instance of the Q31 DCT4 structure.
+ * @param[in] *pState points to state buffer.
+ * @param[in,out] *pInlineBuffer points to the in-place input and output buffer.
+ * @return none.
+ */
+
+ void arm_dct4_q31(
+ const arm_dct4_instance_q31 * S,
+ q31_t * pState,
+ q31_t * pInlineBuffer);
+
+ /**
+ * @brief Instance structure for the Q15 DCT4/IDCT4 function.
+ */
+
+ typedef struct
+ {
+ uint16_t N; /**< length of the DCT4. */
+ uint16_t Nby2; /**< half of the length of the DCT4. */
+ q15_t normalize; /**< normalizing factor. */
+ q15_t *pTwiddle; /**< points to the twiddle factor table. */
+ q15_t *pCosFactor; /**< points to the cosFactor table. */
+ arm_rfft_instance_q15 *pRfft; /**< points to the real FFT instance. */
+ arm_cfft_radix4_instance_q15 *pCfft; /**< points to the complex FFT instance. */
+ } arm_dct4_instance_q15;
+
+ /**
+ * @brief Initialization function for the Q15 DCT4/IDCT4.
+ * @param[in,out] *S points to an instance of Q15 DCT4/IDCT4 structure.
+ * @param[in] *S_RFFT points to an instance of Q15 RFFT/RIFFT structure.
+ * @param[in] *S_CFFT points to an instance of Q15 CFFT/CIFFT structure.
+ * @param[in] N length of the DCT4.
+ * @param[in] Nby2 half of the length of the DCT4.
+ * @param[in] normalize normalizing factor.
+ * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if N is not a supported transform length.
+ */
+
+ arm_status arm_dct4_init_q15(
+ arm_dct4_instance_q15 * S,
+ arm_rfft_instance_q15 * S_RFFT,
+ arm_cfft_radix4_instance_q15 * S_CFFT,
+ uint16_t N,
+ uint16_t Nby2,
+ q15_t normalize);
+
+ /**
+ * @brief Processing function for the Q15 DCT4/IDCT4.
+ * @param[in] *S points to an instance of the Q15 DCT4 structure.
+ * @param[in] *pState points to state buffer.
+ * @param[in,out] *pInlineBuffer points to the in-place input and output buffer.
+ * @return none.
+ */
+
+ void arm_dct4_q15(
+ const arm_dct4_instance_q15 * S,
+ q15_t * pState,
+ q15_t * pInlineBuffer);
+
+ /**
+ * @brief Floating-point vector addition.
+ * @param[in] *pSrcA points to the first input vector
+ * @param[in] *pSrcB points to the second input vector
+ * @param[out] *pDst points to the output vector
+ * @param[in] blockSize number of samples in each vector
+ * @return none.
+ */
+
+ void arm_add_f32(
+ float32_t * pSrcA,
+ float32_t * pSrcB,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Q7 vector addition.
+ * @param[in] *pSrcA points to the first input vector
+ * @param[in] *pSrcB points to the second input vector
+ * @param[out] *pDst points to the output vector
+ * @param[in] blockSize number of samples in each vector
+ * @return none.
+ */
+
+ void arm_add_q7(
+ q7_t * pSrcA,
+ q7_t * pSrcB,
+ q7_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Q15 vector addition.
+ * @param[in] *pSrcA points to the first input vector
+ * @param[in] *pSrcB points to the second input vector
+ * @param[out] *pDst points to the output vector
+ * @param[in] blockSize number of samples in each vector
+ * @return none.
+ */
+
+ void arm_add_q15(
+ q15_t * pSrcA,
+ q15_t * pSrcB,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Q31 vector addition.
+ * @param[in] *pSrcA points to the first input vector
+ * @param[in] *pSrcB points to the second input vector
+ * @param[out] *pDst points to the output vector
+ * @param[in] blockSize number of samples in each vector
+ * @return none.
+ */
+
+ void arm_add_q31(
+ q31_t * pSrcA,
+ q31_t * pSrcB,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Floating-point vector subtraction.
+ * @param[in] *pSrcA points to the first input vector
+ * @param[in] *pSrcB points to the second input vector
+ * @param[out] *pDst points to the output vector
+ * @param[in] blockSize number of samples in each vector
+ * @return none.
+ */
+
+ void arm_sub_f32(
+ float32_t * pSrcA,
+ float32_t * pSrcB,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Q7 vector subtraction.
+ * @param[in] *pSrcA points to the first input vector
+ * @param[in] *pSrcB points to the second input vector
+ * @param[out] *pDst points to the output vector
+ * @param[in] blockSize number of samples in each vector
+ * @return none.
+ */
+
+ void arm_sub_q7(
+ q7_t * pSrcA,
+ q7_t * pSrcB,
+ q7_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Q15 vector subtraction.
+ * @param[in] *pSrcA points to the first input vector
+ * @param[in] *pSrcB points to the second input vector
+ * @param[out] *pDst points to the output vector
+ * @param[in] blockSize number of samples in each vector
+ * @return none.
+ */
+
+ void arm_sub_q15(
+ q15_t * pSrcA,
+ q15_t * pSrcB,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Q31 vector subtraction.
+ * @param[in] *pSrcA points to the first input vector
+ * @param[in] *pSrcB points to the second input vector
+ * @param[out] *pDst points to the output vector
+ * @param[in] blockSize number of samples in each vector
+ * @return none.
+ */
+
+ void arm_sub_q31(
+ q31_t * pSrcA,
+ q31_t * pSrcB,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Multiplies a floating-point vector by a scalar.
+ * @param[in] *pSrc points to the input vector
+ * @param[in] scale scale factor to be applied
+ * @param[out] *pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ * @return none.
+ */
+
+ void arm_scale_f32(
+ float32_t * pSrc,
+ float32_t scale,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Multiplies a Q7 vector by a scalar.
+ * @param[in] *pSrc points to the input vector
+ * @param[in] scaleFract fractional portion of the scale value
+ * @param[in] shift number of bits to shift the result by
+ * @param[out] *pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ * @return none.
+ */
+
+ void arm_scale_q7(
+ q7_t * pSrc,
+ q7_t scaleFract,
+ int8_t shift,
+ q7_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Multiplies a Q15 vector by a scalar.
+ * @param[in] *pSrc points to the input vector
+ * @param[in] scaleFract fractional portion of the scale value
+ * @param[in] shift number of bits to shift the result by
+ * @param[out] *pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ * @return none.
+ */
+
+ void arm_scale_q15(
+ q15_t * pSrc,
+ q15_t scaleFract,
+ int8_t shift,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Multiplies a Q31 vector by a scalar.
+ * @param[in] *pSrc points to the input vector
+ * @param[in] scaleFract fractional portion of the scale value
+ * @param[in] shift number of bits to shift the result by
+ * @param[out] *pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ * @return none.
+ */
+
+ void arm_scale_q31(
+ q31_t * pSrc,
+ q31_t scaleFract,
+ int8_t shift,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Q7 vector absolute value.
+ * @param[in] *pSrc points to the input buffer
+ * @param[out] *pDst points to the output buffer
+ * @param[in] blockSize number of samples in each vector
+ * @return none.
+ */
+
+ void arm_abs_q7(
+ q7_t * pSrc,
+ q7_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Floating-point vector absolute value.
+ * @param[in] *pSrc points to the input buffer
+ * @param[out] *pDst points to the output buffer
+ * @param[in] blockSize number of samples in each vector
+ * @return none.
+ */
+
+ void arm_abs_f32(
+ float32_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Q15 vector absolute value.
+ * @param[in] *pSrc points to the input buffer
+ * @param[out] *pDst points to the output buffer
+ * @param[in] blockSize number of samples in each vector
+ * @return none.
+ */
+
+ void arm_abs_q15(
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Q31 vector absolute value.
+ * @param[in] *pSrc points to the input buffer
+ * @param[out] *pDst points to the output buffer
+ * @param[in] blockSize number of samples in each vector
+ * @return none.
+ */
+
+ void arm_abs_q31(
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Dot product of floating-point vectors.
+ * @param[in] *pSrcA points to the first input vector
+ * @param[in] *pSrcB points to the second input vector
+ * @param[in] blockSize number of samples in each vector
+ * @param[out] *result output result returned here
+ * @return none.
+ */
+
+ void arm_dot_prod_f32(
+ float32_t * pSrcA,
+ float32_t * pSrcB,
+ uint32_t blockSize,
+ float32_t * result);
+
+ /**
+ * @brief Dot product of Q7 vectors.
+ * @param[in] *pSrcA points to the first input vector
+ * @param[in] *pSrcB points to the second input vector
+ * @param[in] blockSize number of samples in each vector
+ * @param[out] *result output result returned here
+ * @return none.
+ */
+
+ void arm_dot_prod_q7(
+ q7_t * pSrcA,
+ q7_t * pSrcB,
+ uint32_t blockSize,
+ q31_t * result);
+
+ /**
+ * @brief Dot product of Q15 vectors.
+ * @param[in] *pSrcA points to the first input vector
+ * @param[in] *pSrcB points to the second input vector
+ * @param[in] blockSize number of samples in each vector
+ * @param[out] *result output result returned here
+ * @return none.
+ */
+
+ void arm_dot_prod_q15(
+ q15_t * pSrcA,
+ q15_t * pSrcB,
+ uint32_t blockSize,
+ q63_t * result);
+
+ /**
+ * @brief Dot product of Q31 vectors.
+ * @param[in] *pSrcA points to the first input vector
+ * @param[in] *pSrcB points to the second input vector
+ * @param[in] blockSize number of samples in each vector
+ * @param[out] *result output result returned here
+ * @return none.
+ */
+
+ void arm_dot_prod_q31(
+ q31_t * pSrcA,
+ q31_t * pSrcB,
+ uint32_t blockSize,
+ q63_t * result);
+
+ /**
+ * @brief Shifts the elements of a Q7 vector a specified number of bits.
+ * @param[in] *pSrc points to the input vector
+ * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right.
+ * @param[out] *pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ * @return none.
+ */
+
+ void arm_shift_q7(
+ q7_t * pSrc,
+ int8_t shiftBits,
+ q7_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Shifts the elements of a Q15 vector a specified number of bits.
+ * @param[in] *pSrc points to the input vector
+ * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right.
+ * @param[out] *pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ * @return none.
+ */
+
+ void arm_shift_q15(
+ q15_t * pSrc,
+ int8_t shiftBits,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Shifts the elements of a Q31 vector a specified number of bits.
+ * @param[in] *pSrc points to the input vector
+ * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right.
+ * @param[out] *pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ * @return none.
+ */
+
+ void arm_shift_q31(
+ q31_t * pSrc,
+ int8_t shiftBits,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Adds a constant offset to a floating-point vector.
+ * @param[in] *pSrc points to the input vector
+ * @param[in] offset is the offset to be added
+ * @param[out] *pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ * @return none.
+ */
+
+ void arm_offset_f32(
+ float32_t * pSrc,
+ float32_t offset,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Adds a constant offset to a Q7 vector.
+ * @param[in] *pSrc points to the input vector
+ * @param[in] offset is the offset to be added
+ * @param[out] *pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ * @return none.
+ */
+
+ void arm_offset_q7(
+ q7_t * pSrc,
+ q7_t offset,
+ q7_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Adds a constant offset to a Q15 vector.
+ * @param[in] *pSrc points to the input vector
+ * @param[in] offset is the offset to be added
+ * @param[out] *pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ * @return none.
+ */
+
+ void arm_offset_q15(
+ q15_t * pSrc,
+ q15_t offset,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Adds a constant offset to a Q31 vector.
+ * @param[in] *pSrc points to the input vector
+ * @param[in] offset is the offset to be added
+ * @param[out] *pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ * @return none.
+ */
+
+ void arm_offset_q31(
+ q31_t * pSrc,
+ q31_t offset,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Negates the elements of a floating-point vector.
+ * @param[in] *pSrc points to the input vector
+ * @param[out] *pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ * @return none.
+ */
+
+ void arm_negate_f32(
+ float32_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Negates the elements of a Q7 vector.
+ * @param[in] *pSrc points to the input vector
+ * @param[out] *pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ * @return none.
+ */
+
+ void arm_negate_q7(
+ q7_t * pSrc,
+ q7_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Negates the elements of a Q15 vector.
+ * @param[in] *pSrc points to the input vector
+ * @param[out] *pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ * @return none.
+ */
+
+ void arm_negate_q15(
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Negates the elements of a Q31 vector.
+ * @param[in] *pSrc points to the input vector
+ * @param[out] *pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ * @return none.
+ */
+
+ void arm_negate_q31(
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+ /**
+ * @brief Copies the elements of a floating-point vector.
+ * @param[in] *pSrc input pointer
+ * @param[out] *pDst output pointer
+ * @param[in] blockSize number of samples to process
+ * @return none.
+ */
+ void arm_copy_f32(
+ float32_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Copies the elements of a Q7 vector.
+ * @param[in] *pSrc input pointer
+ * @param[out] *pDst output pointer
+ * @param[in] blockSize number of samples to process
+ * @return none.
+ */
+ void arm_copy_q7(
+ q7_t * pSrc,
+ q7_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Copies the elements of a Q15 vector.
+ * @param[in] *pSrc input pointer
+ * @param[out] *pDst output pointer
+ * @param[in] blockSize number of samples to process
+ * @return none.
+ */
+ void arm_copy_q15(
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Copies the elements of a Q31 vector.
+ * @param[in] *pSrc input pointer
+ * @param[out] *pDst output pointer
+ * @param[in] blockSize number of samples to process
+ * @return none.
+ */
+ void arm_copy_q31(
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+ /**
+ * @brief Fills a constant value into a floating-point vector.
+ * @param[in] value input value to be filled
+ * @param[out] *pDst output pointer
+ * @param[in] blockSize number of samples to process
+ * @return none.
+ */
+ void arm_fill_f32(
+ float32_t value,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Fills a constant value into a Q7 vector.
+ * @param[in] value input value to be filled
+ * @param[out] *pDst output pointer
+ * @param[in] blockSize number of samples to process
+ * @return none.
+ */
+ void arm_fill_q7(
+ q7_t value,
+ q7_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Fills a constant value into a Q15 vector.
+ * @param[in] value input value to be filled
+ * @param[out] *pDst output pointer
+ * @param[in] blockSize number of samples to process
+ * @return none.
+ */
+ void arm_fill_q15(
+ q15_t value,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Fills a constant value into a Q31 vector.
+ * @param[in] value input value to be filled
+ * @param[out] *pDst output pointer
+ * @param[in] blockSize number of samples to process
+ * @return none.
+ */
+ void arm_fill_q31(
+ q31_t value,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+/**
+ * @brief Convolution of floating-point sequences.
+ * @param[in] *pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] *pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] *pDst points to the location where the output result is written. Length srcALen+srcBLen-1.
+ * @return none.
+ */
+
+ void arm_conv_f32(
+ float32_t * pSrcA,
+ uint32_t srcALen,
+ float32_t * pSrcB,
+ uint32_t srcBLen,
+ float32_t * pDst);
+
+/**
+ * @brief Convolution of Q15 sequences.
+ * @param[in] *pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] *pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] *pDst points to the location where the output result is written. Length srcALen+srcBLen-1.
+ * @return none.
+ */
+
+ void arm_conv_q15(
+ q15_t * pSrcA,
+ uint32_t srcALen,
+ q15_t * pSrcB,
+ uint32_t srcBLen,
+ q15_t * pDst);
+
+ /**
+ * @brief Convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4
+ * @param[in] *pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] *pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] *pDst points to the block of output data Length srcALen+srcBLen-1.
+ * @return none.
+ */
+
+ void arm_conv_fast_q15(
+ q15_t * pSrcA,
+ uint32_t srcALen,
+ q15_t * pSrcB,
+ uint32_t srcBLen,
+ q15_t * pDst);
+
+ /**
+ * @brief Convolution of Q31 sequences.
+ * @param[in] *pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] *pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] *pDst points to the block of output data Length srcALen+srcBLen-1.
+ * @return none.
+ */
+
+ void arm_conv_q31(
+ q31_t * pSrcA,
+ uint32_t srcALen,
+ q31_t * pSrcB,
+ uint32_t srcBLen,
+ q31_t * pDst);
+
+ /**
+ * @brief Convolution of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4
+ * @param[in] *pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] *pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] *pDst points to the block of output data Length srcALen+srcBLen-1.
+ * @return none.
+ */
+
+ void arm_conv_fast_q31(
+ q31_t * pSrcA,
+ uint32_t srcALen,
+ q31_t * pSrcB,
+ uint32_t srcBLen,
+ q31_t * pDst);
+
+ /**
+ * @brief Convolution of Q7 sequences.
+ * @param[in] *pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] *pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] *pDst points to the block of output data Length srcALen+srcBLen-1.
+ * @return none.
+ */
+
+ void arm_conv_q7(
+ q7_t * pSrcA,
+ uint32_t srcALen,
+ q7_t * pSrcB,
+ uint32_t srcBLen,
+ q7_t * pDst);
+
+ /**
+ * @brief Partial convolution of floating-point sequences.
+ * @param[in] *pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] *pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] *pDst points to the block of output data
+ * @param[in] firstIndex is the first output sample to start with.
+ * @param[in] numPoints is the number of output points to be computed.
+ * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2].
+ */
+
+ arm_status arm_conv_partial_f32(
+ float32_t * pSrcA,
+ uint32_t srcALen,
+ float32_t * pSrcB,
+ uint32_t srcBLen,
+ float32_t * pDst,
+ uint32_t firstIndex,
+ uint32_t numPoints);
+
+ /**
+ * @brief Partial convolution of Q15 sequences.
+ * @param[in] *pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] *pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] *pDst points to the block of output data
+ * @param[in] firstIndex is the first output sample to start with.
+ * @param[in] numPoints is the number of output points to be computed.
+ * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2].
+ */
+
+ arm_status arm_conv_partial_q15(
+ q15_t * pSrcA,
+ uint32_t srcALen,
+ q15_t * pSrcB,
+ uint32_t srcBLen,
+ q15_t * pDst,
+ uint32_t firstIndex,
+ uint32_t numPoints);
+
+ /**
+ * @brief Partial convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4
+ * @param[in] *pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] *pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] *pDst points to the block of output data
+ * @param[in] firstIndex is the first output sample to start with.
+ * @param[in] numPoints is the number of output points to be computed.
+ * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2].
+ */
+
+ arm_status arm_conv_partial_fast_q15(
+ q15_t * pSrcA,
+ uint32_t srcALen,
+ q15_t * pSrcB,
+ uint32_t srcBLen,
+ q15_t * pDst,
+ uint32_t firstIndex,
+ uint32_t numPoints);
+
+ /**
+ * @brief Partial convolution of Q31 sequences.
+ * @param[in] *pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] *pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] *pDst points to the block of output data
+ * @param[in] firstIndex is the first output sample to start with.
+ * @param[in] numPoints is the number of output points to be computed.
+ * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2].
+ */
+
+ arm_status arm_conv_partial_q31(
+ q31_t * pSrcA,
+ uint32_t srcALen,
+ q31_t * pSrcB,
+ uint32_t srcBLen,
+ q31_t * pDst,
+ uint32_t firstIndex,
+ uint32_t numPoints);
+
+
+ /**
+ * @brief Partial convolution of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4
+ * @param[in] *pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] *pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] *pDst points to the block of output data
+ * @param[in] firstIndex is the first output sample to start with.
+ * @param[in] numPoints is the number of output points to be computed.
+ * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2].
+ */
+
+ arm_status arm_conv_partial_fast_q31(
+ q31_t * pSrcA,
+ uint32_t srcALen,
+ q31_t * pSrcB,
+ uint32_t srcBLen,
+ q31_t * pDst,
+ uint32_t firstIndex,
+ uint32_t numPoints);
+
+ /**
+ * @brief Partial convolution of Q7 sequences.
+ * @param[in] *pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] *pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] *pDst points to the block of output data
+ * @param[in] firstIndex is the first output sample to start with.
+ * @param[in] numPoints is the number of output points to be computed.
+ * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2].
+ */
+
+ arm_status arm_conv_partial_q7(
+ q7_t * pSrcA,
+ uint32_t srcALen,
+ q7_t * pSrcB,
+ uint32_t srcBLen,
+ q7_t * pDst,
+ uint32_t firstIndex,
+ uint32_t numPoints);
+
+
+ /**
+ * @brief Instance structure for the Q15 FIR decimator.
+ */
+
+ typedef struct
+ {
+ uint8_t M; /**< decimation factor. */
+ uint16_t numTaps; /**< number of coefficients in the filter. */
+ q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/
+ q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+ } arm_fir_decimate_instance_q15;
+
+ /**
+ * @brief Instance structure for the Q31 FIR decimator.
+ */
+
+ typedef struct
+ {
+ uint8_t M; /**< decimation factor. */
+ uint16_t numTaps; /**< number of coefficients in the filter. */
+ q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/
+ q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+
+ } arm_fir_decimate_instance_q31;
+
+ /**
+ * @brief Instance structure for the floating-point FIR decimator.
+ */
+
+ typedef struct
+ {
+ uint8_t M; /**< decimation factor. */
+ uint16_t numTaps; /**< number of coefficients in the filter. */
+ float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/
+ float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+
+ } arm_fir_decimate_instance_f32;
+
+
+
+ /**
+ * @brief Processing function for the floating-point FIR decimator.
+ * @param[in] *S points to an instance of the floating-point FIR decimator structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data
+ * @param[in] blockSize number of input samples to process per call.
+ * @return none
+ */
+
+ void arm_fir_decimate_f32(
+ const arm_fir_decimate_instance_f32 * S,
+ float32_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for the floating-point FIR decimator.
+ * @param[in,out] *S points to an instance of the floating-point FIR decimator structure.
+ * @param[in] numTaps number of coefficients in the filter.
+ * @param[in] M decimation factor.
+ * @param[in] *pCoeffs points to the filter coefficients.
+ * @param[in] *pState points to the state buffer.
+ * @param[in] blockSize number of input samples to process per call.
+ * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if
+ * blockSize is not a multiple of M.
+ */
+
+ arm_status arm_fir_decimate_init_f32(
+ arm_fir_decimate_instance_f32 * S,
+ uint16_t numTaps,
+ uint8_t M,
+ float32_t * pCoeffs,
+ float32_t * pState,
+ uint32_t blockSize);
+
+ /**
+ * @brief Processing function for the Q15 FIR decimator.
+ * @param[in] *S points to an instance of the Q15 FIR decimator structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data
+ * @param[in] blockSize number of input samples to process per call.
+ * @return none
+ */
+
+ void arm_fir_decimate_q15(
+ const arm_fir_decimate_instance_q15 * S,
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Processing function for the Q15 FIR decimator (fast variant) for Cortex-M3 and Cortex-M4.
+ * @param[in] *S points to an instance of the Q15 FIR decimator structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data
+ * @param[in] blockSize number of input samples to process per call.
+ * @return none
+ */
+
+ void arm_fir_decimate_fast_q15(
+ const arm_fir_decimate_instance_q15 * S,
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+
+
+ /**
+ * @brief Initialization function for the Q15 FIR decimator.
+ * @param[in,out] *S points to an instance of the Q15 FIR decimator structure.
+ * @param[in] numTaps number of coefficients in the filter.
+ * @param[in] M decimation factor.
+ * @param[in] *pCoeffs points to the filter coefficients.
+ * @param[in] *pState points to the state buffer.
+ * @param[in] blockSize number of input samples to process per call.
+ * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if
+ * blockSize is not a multiple of M.
+ */
+
+ arm_status arm_fir_decimate_init_q15(
+ arm_fir_decimate_instance_q15 * S,
+ uint16_t numTaps,
+ uint8_t M,
+ q15_t * pCoeffs,
+ q15_t * pState,
+ uint32_t blockSize);
+
+ /**
+ * @brief Processing function for the Q31 FIR decimator.
+ * @param[in] *S points to an instance of the Q31 FIR decimator structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data
+ * @param[in] blockSize number of input samples to process per call.
+ * @return none
+ */
+
+ void arm_fir_decimate_q31(
+ const arm_fir_decimate_instance_q31 * S,
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Processing function for the Q31 FIR decimator (fast variant) for Cortex-M3 and Cortex-M4.
+ * @param[in] *S points to an instance of the Q31 FIR decimator structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data
+ * @param[in] blockSize number of input samples to process per call.
+ * @return none
+ */
+
+ void arm_fir_decimate_fast_q31(
+ arm_fir_decimate_instance_q31 * S,
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for the Q31 FIR decimator.
+ * @param[in,out] *S points to an instance of the Q31 FIR decimator structure.
+ * @param[in] numTaps number of coefficients in the filter.
+ * @param[in] M decimation factor.
+ * @param[in] *pCoeffs points to the filter coefficients.
+ * @param[in] *pState points to the state buffer.
+ * @param[in] blockSize number of input samples to process per call.
+ * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if
+ * blockSize is not a multiple of M.
+ */
+
+ arm_status arm_fir_decimate_init_q31(
+ arm_fir_decimate_instance_q31 * S,
+ uint16_t numTaps,
+ uint8_t M,
+ q31_t * pCoeffs,
+ q31_t * pState,
+ uint32_t blockSize);
+
+
+
+ /**
+ * @brief Instance structure for the Q15 FIR interpolator.
+ */
+
+ typedef struct
+ {
+ uint8_t L; /**< upsample factor. */
+ uint16_t phaseLength; /**< length of each polyphase filter component. */
+ q15_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */
+ q15_t *pState; /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */
+ } arm_fir_interpolate_instance_q15;
+
+ /**
+ * @brief Instance structure for the Q31 FIR interpolator.
+ */
+
+ typedef struct
+ {
+ uint8_t L; /**< upsample factor. */
+ uint16_t phaseLength; /**< length of each polyphase filter component. */
+ q31_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */
+ q31_t *pState; /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */
+ } arm_fir_interpolate_instance_q31;
+
+ /**
+ * @brief Instance structure for the floating-point FIR interpolator.
+ */
+
+ typedef struct
+ {
+ uint8_t L; /**< upsample factor. */
+ uint16_t phaseLength; /**< length of each polyphase filter component. */
+ float32_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */
+ float32_t *pState; /**< points to the state variable array. The array is of length phaseLength+numTaps-1. */
+ } arm_fir_interpolate_instance_f32;
+
+
+ /**
+ * @brief Processing function for the Q15 FIR interpolator.
+ * @param[in] *S points to an instance of the Q15 FIR interpolator structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data.
+ * @param[in] blockSize number of input samples to process per call.
+ * @return none.
+ */
+
+ void arm_fir_interpolate_q15(
+ const arm_fir_interpolate_instance_q15 * S,
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for the Q15 FIR interpolator.
+ * @param[in,out] *S points to an instance of the Q15 FIR interpolator structure.
+ * @param[in] L upsample factor.
+ * @param[in] numTaps number of filter coefficients in the filter.
+ * @param[in] *pCoeffs points to the filter coefficient buffer.
+ * @param[in] *pState points to the state buffer.
+ * @param[in] blockSize number of input samples to process per call.
+ * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if
+ * the filter length numTaps is not a multiple of the interpolation factor L.
+ */
+
+ arm_status arm_fir_interpolate_init_q15(
+ arm_fir_interpolate_instance_q15 * S,
+ uint8_t L,
+ uint16_t numTaps,
+ q15_t * pCoeffs,
+ q15_t * pState,
+ uint32_t blockSize);
+
+ /**
+ * @brief Processing function for the Q31 FIR interpolator.
+ * @param[in] *S points to an instance of the Q15 FIR interpolator structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data.
+ * @param[in] blockSize number of input samples to process per call.
+ * @return none.
+ */
+
+ void arm_fir_interpolate_q31(
+ const arm_fir_interpolate_instance_q31 * S,
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Initialization function for the Q31 FIR interpolator.
+ * @param[in,out] *S points to an instance of the Q31 FIR interpolator structure.
+ * @param[in] L upsample factor.
+ * @param[in] numTaps number of filter coefficients in the filter.
+ * @param[in] *pCoeffs points to the filter coefficient buffer.
+ * @param[in] *pState points to the state buffer.
+ * @param[in] blockSize number of input samples to process per call.
+ * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if
+ * the filter length numTaps is not a multiple of the interpolation factor L.
+ */
+
+ arm_status arm_fir_interpolate_init_q31(
+ arm_fir_interpolate_instance_q31 * S,
+ uint8_t L,
+ uint16_t numTaps,
+ q31_t * pCoeffs,
+ q31_t * pState,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Processing function for the floating-point FIR interpolator.
+ * @param[in] *S points to an instance of the floating-point FIR interpolator structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data.
+ * @param[in] blockSize number of input samples to process per call.
+ * @return none.
+ */
+
+ void arm_fir_interpolate_f32(
+ const arm_fir_interpolate_instance_f32 * S,
+ float32_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Initialization function for the floating-point FIR interpolator.
+ * @param[in,out] *S points to an instance of the floating-point FIR interpolator structure.
+ * @param[in] L upsample factor.
+ * @param[in] numTaps number of filter coefficients in the filter.
+ * @param[in] *pCoeffs points to the filter coefficient buffer.
+ * @param[in] *pState points to the state buffer.
+ * @param[in] blockSize number of input samples to process per call.
+ * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if
+ * the filter length numTaps is not a multiple of the interpolation factor L.
+ */
+
+ arm_status arm_fir_interpolate_init_f32(
+ arm_fir_interpolate_instance_f32 * S,
+ uint8_t L,
+ uint16_t numTaps,
+ float32_t * pCoeffs,
+ float32_t * pState,
+ uint32_t blockSize);
+
+ /**
+ * @brief Instance structure for the high precision Q31 Biquad cascade filter.
+ */
+
+ typedef struct
+ {
+ uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */
+ q63_t *pState; /**< points to the array of state coefficients. The array is of length 4*numStages. */
+ q31_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */
+ uint8_t postShift; /**< additional shift, in bits, applied to each output sample. */
+
+ } arm_biquad_cas_df1_32x64_ins_q31;
+
+
+ /**
+ * @param[in] *S points to an instance of the high precision Q31 Biquad cascade filter structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data
+ * @param[in] blockSize number of samples to process.
+ * @return none.
+ */
+
+ void arm_biquad_cas_df1_32x64_q31(
+ const arm_biquad_cas_df1_32x64_ins_q31 * S,
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @param[in,out] *S points to an instance of the high precision Q31 Biquad cascade filter structure.
+ * @param[in] numStages number of 2nd order stages in the filter.
+ * @param[in] *pCoeffs points to the filter coefficients.
+ * @param[in] *pState points to the state buffer.
+ * @param[in] postShift shift to be applied to the output. Varies according to the coefficients format
+ * @return none
+ */
+
+ void arm_biquad_cas_df1_32x64_init_q31(
+ arm_biquad_cas_df1_32x64_ins_q31 * S,
+ uint8_t numStages,
+ q31_t * pCoeffs,
+ q63_t * pState,
+ uint8_t postShift);
+
+
+
+ /**
+ * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter.
+ */
+
+ typedef struct
+ {
+ uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */
+ float32_t *pState; /**< points to the array of state coefficients. The array is of length 2*numStages. */
+ float32_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */
+ } arm_biquad_cascade_df2T_instance_f32;
+
+
+ /**
+ * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter.
+ * @param[in] *S points to an instance of the filter data structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data
+ * @param[in] blockSize number of samples to process.
+ * @return none.
+ */
+
+ void arm_biquad_cascade_df2T_f32(
+ const arm_biquad_cascade_df2T_instance_f32 * S,
+ float32_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter.
+ * @param[in,out] *S points to an instance of the filter data structure.
+ * @param[in] numStages number of 2nd order stages in the filter.
+ * @param[in] *pCoeffs points to the filter coefficients.
+ * @param[in] *pState points to the state buffer.
+ * @return none
+ */
+
+ void arm_biquad_cascade_df2T_init_f32(
+ arm_biquad_cascade_df2T_instance_f32 * S,
+ uint8_t numStages,
+ float32_t * pCoeffs,
+ float32_t * pState);
+
+
+
+ /**
+ * @brief Instance structure for the Q15 FIR lattice filter.
+ */
+
+ typedef struct
+ {
+ uint16_t numStages; /**< number of filter stages. */
+ q15_t *pState; /**< points to the state variable array. The array is of length numStages. */
+ q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */
+ } arm_fir_lattice_instance_q15;
+
+ /**
+ * @brief Instance structure for the Q31 FIR lattice filter.
+ */
+
+ typedef struct
+ {
+ uint16_t numStages; /**< number of filter stages. */
+ q31_t *pState; /**< points to the state variable array. The array is of length numStages. */
+ q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */
+ } arm_fir_lattice_instance_q31;
+
+ /**
+ * @brief Instance structure for the floating-point FIR lattice filter.
+ */
+
+ typedef struct
+ {
+ uint16_t numStages; /**< number of filter stages. */
+ float32_t *pState; /**< points to the state variable array. The array is of length numStages. */
+ float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */
+ } arm_fir_lattice_instance_f32;
+
+ /**
+ * @brief Initialization function for the Q15 FIR lattice filter.
+ * @param[in] *S points to an instance of the Q15 FIR lattice structure.
+ * @param[in] numStages number of filter stages.
+ * @param[in] *pCoeffs points to the coefficient buffer. The array is of length numStages.
+ * @param[in] *pState points to the state buffer. The array is of length numStages.
+ * @return none.
+ */
+
+ void arm_fir_lattice_init_q15(
+ arm_fir_lattice_instance_q15 * S,
+ uint16_t numStages,
+ q15_t * pCoeffs,
+ q15_t * pState);
+
+
+ /**
+ * @brief Processing function for the Q15 FIR lattice filter.
+ * @param[in] *S points to an instance of the Q15 FIR lattice structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ * @return none.
+ */
+ void arm_fir_lattice_q15(
+ const arm_fir_lattice_instance_q15 * S,
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Initialization function for the Q31 FIR lattice filter.
+ * @param[in] *S points to an instance of the Q31 FIR lattice structure.
+ * @param[in] numStages number of filter stages.
+ * @param[in] *pCoeffs points to the coefficient buffer. The array is of length numStages.
+ * @param[in] *pState points to the state buffer. The array is of length numStages.
+ * @return none.
+ */
+
+ void arm_fir_lattice_init_q31(
+ arm_fir_lattice_instance_q31 * S,
+ uint16_t numStages,
+ q31_t * pCoeffs,
+ q31_t * pState);
+
+
+ /**
+ * @brief Processing function for the Q31 FIR lattice filter.
+ * @param[in] *S points to an instance of the Q31 FIR lattice structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data
+ * @param[in] blockSize number of samples to process.
+ * @return none.
+ */
+
+ void arm_fir_lattice_q31(
+ const arm_fir_lattice_instance_q31 * S,
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+/**
+ * @brief Initialization function for the floating-point FIR lattice filter.
+ * @param[in] *S points to an instance of the floating-point FIR lattice structure.
+ * @param[in] numStages number of filter stages.
+ * @param[in] *pCoeffs points to the coefficient buffer. The array is of length numStages.
+ * @param[in] *pState points to the state buffer. The array is of length numStages.
+ * @return none.
+ */
+
+ void arm_fir_lattice_init_f32(
+ arm_fir_lattice_instance_f32 * S,
+ uint16_t numStages,
+ float32_t * pCoeffs,
+ float32_t * pState);
+
+ /**
+ * @brief Processing function for the floating-point FIR lattice filter.
+ * @param[in] *S points to an instance of the floating-point FIR lattice structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data
+ * @param[in] blockSize number of samples to process.
+ * @return none.
+ */
+
+ void arm_fir_lattice_f32(
+ const arm_fir_lattice_instance_f32 * S,
+ float32_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Instance structure for the Q15 IIR lattice filter.
+ */
+ typedef struct
+ {
+ uint16_t numStages; /**< number of stages in the filter. */
+ q15_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */
+ q15_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */
+ q15_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */
+ } arm_iir_lattice_instance_q15;
+
+ /**
+ * @brief Instance structure for the Q31 IIR lattice filter.
+ */
+ typedef struct
+ {
+ uint16_t numStages; /**< number of stages in the filter. */
+ q31_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */
+ q31_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */
+ q31_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */
+ } arm_iir_lattice_instance_q31;
+
+ /**
+ * @brief Instance structure for the floating-point IIR lattice filter.
+ */
+ typedef struct
+ {
+ uint16_t numStages; /**< number of stages in the filter. */
+ float32_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */
+ float32_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */
+ float32_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */
+ } arm_iir_lattice_instance_f32;
+
+ /**
+ * @brief Processing function for the floating-point IIR lattice filter.
+ * @param[in] *S points to an instance of the floating-point IIR lattice structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ * @return none.
+ */
+
+ void arm_iir_lattice_f32(
+ const arm_iir_lattice_instance_f32 * S,
+ float32_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Initialization function for the floating-point IIR lattice filter.
+ * @param[in] *S points to an instance of the floating-point IIR lattice structure.
+ * @param[in] numStages number of stages in the filter.
+ * @param[in] *pkCoeffs points to the reflection coefficient buffer. The array is of length numStages.
+ * @param[in] *pvCoeffs points to the ladder coefficient buffer. The array is of length numStages+1.
+ * @param[in] *pState points to the state buffer. The array is of length numStages+blockSize-1.
+ * @param[in] blockSize number of samples to process.
+ * @return none.
+ */
+
+ void arm_iir_lattice_init_f32(
+ arm_iir_lattice_instance_f32 * S,
+ uint16_t numStages,
+ float32_t *pkCoeffs,
+ float32_t *pvCoeffs,
+ float32_t *pState,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Processing function for the Q31 IIR lattice filter.
+ * @param[in] *S points to an instance of the Q31 IIR lattice structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ * @return none.
+ */
+
+ void arm_iir_lattice_q31(
+ const arm_iir_lattice_instance_q31 * S,
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for the Q31 IIR lattice filter.
+ * @param[in] *S points to an instance of the Q31 IIR lattice structure.
+ * @param[in] numStages number of stages in the filter.
+ * @param[in] *pkCoeffs points to the reflection coefficient buffer. The array is of length numStages.
+ * @param[in] *pvCoeffs points to the ladder coefficient buffer. The array is of length numStages+1.
+ * @param[in] *pState points to the state buffer. The array is of length numStages+blockSize.
+ * @param[in] blockSize number of samples to process.
+ * @return none.
+ */
+
+ void arm_iir_lattice_init_q31(
+ arm_iir_lattice_instance_q31 * S,
+ uint16_t numStages,
+ q31_t *pkCoeffs,
+ q31_t *pvCoeffs,
+ q31_t *pState,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Processing function for the Q15 IIR lattice filter.
+ * @param[in] *S points to an instance of the Q15 IIR lattice structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ * @return none.
+ */
+
+ void arm_iir_lattice_q15(
+ const arm_iir_lattice_instance_q15 * S,
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+
+/**
+ * @brief Initialization function for the Q15 IIR lattice filter.
+ * @param[in] *S points to an instance of the fixed-point Q15 IIR lattice structure.
+ * @param[in] numStages number of stages in the filter.
+ * @param[in] *pkCoeffs points to reflection coefficient buffer. The array is of length numStages.
+ * @param[in] *pvCoeffs points to ladder coefficient buffer. The array is of length numStages+1.
+ * @param[in] *pState points to state buffer. The array is of length numStages+blockSize.
+ * @param[in] blockSize number of samples to process per call.
+ * @return none.
+ */
+
+ void arm_iir_lattice_init_q15(
+ arm_iir_lattice_instance_q15 * S,
+ uint16_t numStages,
+ q15_t *pkCoeffs,
+ q15_t *pvCoeffs,
+ q15_t *pState,
+ uint32_t blockSize);
+
+ /**
+ * @brief Instance structure for the floating-point LMS filter.
+ */
+
+ typedef struct
+ {
+ uint16_t numTaps; /**< number of coefficients in the filter. */
+ float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+ float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */
+ float32_t mu; /**< step size that controls filter coefficient updates. */
+ } arm_lms_instance_f32;
+
+ /**
+ * @brief Processing function for floating-point LMS filter.
+ * @param[in] *S points to an instance of the floating-point LMS filter structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[in] *pRef points to the block of reference data.
+ * @param[out] *pOut points to the block of output data.
+ * @param[out] *pErr points to the block of error data.
+ * @param[in] blockSize number of samples to process.
+ * @return none.
+ */
+
+ void arm_lms_f32(
+ const arm_lms_instance_f32 * S,
+ float32_t * pSrc,
+ float32_t * pRef,
+ float32_t * pOut,
+ float32_t * pErr,
+ uint32_t blockSize);
+
+ /**
+ * @brief Initialization function for floating-point LMS filter.
+ * @param[in] *S points to an instance of the floating-point LMS filter structure.
+ * @param[in] numTaps number of filter coefficients.
+ * @param[in] *pCoeffs points to the coefficient buffer.
+ * @param[in] *pState points to state buffer.
+ * @param[in] mu step size that controls filter coefficient updates.
+ * @param[in] blockSize number of samples to process.
+ * @return none.
+ */
+
+ void arm_lms_init_f32(
+ arm_lms_instance_f32 * S,
+ uint16_t numTaps,
+ float32_t * pCoeffs,
+ float32_t * pState,
+ float32_t mu,
+ uint32_t blockSize);
+
+ /**
+ * @brief Instance structure for the Q15 LMS filter.
+ */
+
+ typedef struct
+ {
+ uint16_t numTaps; /**< number of coefficients in the filter. */
+ q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+ q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */
+ q15_t mu; /**< step size that controls filter coefficient updates. */
+ uint32_t postShift; /**< bit shift applied to coefficients. */
+ } arm_lms_instance_q15;
+
+
+ /**
+ * @brief Initialization function for the Q15 LMS filter.
+ * @param[in] *S points to an instance of the Q15 LMS filter structure.
+ * @param[in] numTaps number of filter coefficients.
+ * @param[in] *pCoeffs points to the coefficient buffer.
+ * @param[in] *pState points to the state buffer.
+ * @param[in] mu step size that controls filter coefficient updates.
+ * @param[in] blockSize number of samples to process.
+ * @param[in] postShift bit shift applied to coefficients.
+ * @return none.
+ */
+
+ void arm_lms_init_q15(
+ arm_lms_instance_q15 * S,
+ uint16_t numTaps,
+ q15_t * pCoeffs,
+ q15_t * pState,
+ q15_t mu,
+ uint32_t blockSize,
+ uint32_t postShift);
+
+ /**
+ * @brief Processing function for Q15 LMS filter.
+ * @param[in] *S points to an instance of the Q15 LMS filter structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[in] *pRef points to the block of reference data.
+ * @param[out] *pOut points to the block of output data.
+ * @param[out] *pErr points to the block of error data.
+ * @param[in] blockSize number of samples to process.
+ * @return none.
+ */
+
+ void arm_lms_q15(
+ const arm_lms_instance_q15 * S,
+ q15_t * pSrc,
+ q15_t * pRef,
+ q15_t * pOut,
+ q15_t * pErr,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Instance structure for the Q31 LMS filter.
+ */
+
+ typedef struct
+ {
+ uint16_t numTaps; /**< number of coefficients in the filter. */
+ q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+ q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */
+ q31_t mu; /**< step size that controls filter coefficient updates. */
+ uint32_t postShift; /**< bit shift applied to coefficients. */
+
+ } arm_lms_instance_q31;
+
+ /**
+ * @brief Processing function for Q31 LMS filter.
+ * @param[in] *S points to an instance of the Q15 LMS filter structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[in] *pRef points to the block of reference data.
+ * @param[out] *pOut points to the block of output data.
+ * @param[out] *pErr points to the block of error data.
+ * @param[in] blockSize number of samples to process.
+ * @return none.
+ */
+
+ void arm_lms_q31(
+ const arm_lms_instance_q31 * S,
+ q31_t * pSrc,
+ q31_t * pRef,
+ q31_t * pOut,
+ q31_t * pErr,
+ uint32_t blockSize);
+
+ /**
+ * @brief Initialization function for Q31 LMS filter.
+ * @param[in] *S points to an instance of the Q31 LMS filter structure.
+ * @param[in] numTaps number of filter coefficients.
+ * @param[in] *pCoeffs points to coefficient buffer.
+ * @param[in] *pState points to state buffer.
+ * @param[in] mu step size that controls filter coefficient updates.
+ * @param[in] blockSize number of samples to process.
+ * @param[in] postShift bit shift applied to coefficients.
+ * @return none.
+ */
+
+ void arm_lms_init_q31(
+ arm_lms_instance_q31 * S,
+ uint16_t numTaps,
+ q31_t *pCoeffs,
+ q31_t *pState,
+ q31_t mu,
+ uint32_t blockSize,
+ uint32_t postShift);
+
+ /**
+ * @brief Instance structure for the floating-point normalized LMS filter.
+ */
+
+ typedef struct
+ {
+ uint16_t numTaps; /**< number of coefficients in the filter. */
+ float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+ float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */
+ float32_t mu; /**< step size that control filter coefficient updates. */
+ float32_t energy; /**< saves previous frame energy. */
+ float32_t x0; /**< saves previous input sample. */
+ } arm_lms_norm_instance_f32;
+
+ /**
+ * @brief Processing function for floating-point normalized LMS filter.
+ * @param[in] *S points to an instance of the floating-point normalized LMS filter structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[in] *pRef points to the block of reference data.
+ * @param[out] *pOut points to the block of output data.
+ * @param[out] *pErr points to the block of error data.
+ * @param[in] blockSize number of samples to process.
+ * @return none.
+ */
+
+ void arm_lms_norm_f32(
+ arm_lms_norm_instance_f32 * S,
+ float32_t * pSrc,
+ float32_t * pRef,
+ float32_t * pOut,
+ float32_t * pErr,
+ uint32_t blockSize);
+
+ /**
+ * @brief Initialization function for floating-point normalized LMS filter.
+ * @param[in] *S points to an instance of the floating-point LMS filter structure.
+ * @param[in] numTaps number of filter coefficients.
+ * @param[in] *pCoeffs points to coefficient buffer.
+ * @param[in] *pState points to state buffer.
+ * @param[in] mu step size that controls filter coefficient updates.
+ * @param[in] blockSize number of samples to process.
+ * @return none.
+ */
+
+ void arm_lms_norm_init_f32(
+ arm_lms_norm_instance_f32 * S,
+ uint16_t numTaps,
+ float32_t * pCoeffs,
+ float32_t * pState,
+ float32_t mu,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Instance structure for the Q31 normalized LMS filter.
+ */
+ typedef struct
+ {
+ uint16_t numTaps; /**< number of coefficients in the filter. */
+ q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+ q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */
+ q31_t mu; /**< step size that controls filter coefficient updates. */
+ uint8_t postShift; /**< bit shift applied to coefficients. */
+ q31_t *recipTable; /**< points to the reciprocal initial value table. */
+ q31_t energy; /**< saves previous frame energy. */
+ q31_t x0; /**< saves previous input sample. */
+ } arm_lms_norm_instance_q31;
+
+ /**
+ * @brief Processing function for Q31 normalized LMS filter.
+ * @param[in] *S points to an instance of the Q31 normalized LMS filter structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[in] *pRef points to the block of reference data.
+ * @param[out] *pOut points to the block of output data.
+ * @param[out] *pErr points to the block of error data.
+ * @param[in] blockSize number of samples to process.
+ * @return none.
+ */
+
+ void arm_lms_norm_q31(
+ arm_lms_norm_instance_q31 * S,
+ q31_t * pSrc,
+ q31_t * pRef,
+ q31_t * pOut,
+ q31_t * pErr,
+ uint32_t blockSize);
+
+ /**
+ * @brief Initialization function for Q31 normalized LMS filter.
+ * @param[in] *S points to an instance of the Q31 normalized LMS filter structure.
+ * @param[in] numTaps number of filter coefficients.
+ * @param[in] *pCoeffs points to coefficient buffer.
+ * @param[in] *pState points to state buffer.
+ * @param[in] mu step size that controls filter coefficient updates.
+ * @param[in] blockSize number of samples to process.
+ * @param[in] postShift bit shift applied to coefficients.
+ * @return none.
+ */
+
+ void arm_lms_norm_init_q31(
+ arm_lms_norm_instance_q31 * S,
+ uint16_t numTaps,
+ q31_t * pCoeffs,
+ q31_t * pState,
+ q31_t mu,
+ uint32_t blockSize,
+ uint8_t postShift);
+
+ /**
+ * @brief Instance structure for the Q15 normalized LMS filter.
+ */
+
+ typedef struct
+ {
+ uint16_t numTaps; /**< Number of coefficients in the filter. */
+ q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+ q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */
+ q15_t mu; /**< step size that controls filter coefficient updates. */
+ uint8_t postShift; /**< bit shift applied to coefficients. */
+ q15_t *recipTable; /**< Points to the reciprocal initial value table. */
+ q15_t energy; /**< saves previous frame energy. */
+ q15_t x0; /**< saves previous input sample. */
+ } arm_lms_norm_instance_q15;
+
+ /**
+ * @brief Processing function for Q15 normalized LMS filter.
+ * @param[in] *S points to an instance of the Q15 normalized LMS filter structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[in] *pRef points to the block of reference data.
+ * @param[out] *pOut points to the block of output data.
+ * @param[out] *pErr points to the block of error data.
+ * @param[in] blockSize number of samples to process.
+ * @return none.
+ */
+
+ void arm_lms_norm_q15(
+ arm_lms_norm_instance_q15 * S,
+ q15_t * pSrc,
+ q15_t * pRef,
+ q15_t * pOut,
+ q15_t * pErr,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for Q15 normalized LMS filter.
+ * @param[in] *S points to an instance of the Q15 normalized LMS filter structure.
+ * @param[in] numTaps number of filter coefficients.
+ * @param[in] *pCoeffs points to coefficient buffer.
+ * @param[in] *pState points to state buffer.
+ * @param[in] mu step size that controls filter coefficient updates.
+ * @param[in] blockSize number of samples to process.
+ * @param[in] postShift bit shift applied to coefficients.
+ * @return none.
+ */
+
+ void arm_lms_norm_init_q15(
+ arm_lms_norm_instance_q15 * S,
+ uint16_t numTaps,
+ q15_t * pCoeffs,
+ q15_t * pState,
+ q15_t mu,
+ uint32_t blockSize,
+ uint8_t postShift);
+
+ /**
+ * @brief Correlation of floating-point sequences.
+ * @param[in] *pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] *pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1.
+ * @return none.
+ */
+
+ void arm_correlate_f32(
+ float32_t * pSrcA,
+ uint32_t srcALen,
+ float32_t * pSrcB,
+ uint32_t srcBLen,
+ float32_t * pDst);
+
+ /**
+ * @brief Correlation of Q15 sequences.
+ * @param[in] *pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] *pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1.
+ * @return none.
+ */
+
+ void arm_correlate_q15(
+ q15_t * pSrcA,
+ uint32_t srcALen,
+ q15_t * pSrcB,
+ uint32_t srcBLen,
+ q15_t * pDst);
+
+ /**
+ * @brief Correlation of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4.
+ * @param[in] *pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] *pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1.
+ * @return none.
+ */
+
+ void arm_correlate_fast_q15(
+ q15_t * pSrcA,
+ uint32_t srcALen,
+ q15_t * pSrcB,
+ uint32_t srcBLen,
+ q15_t * pDst);
+
+ /**
+ * @brief Correlation of Q31 sequences.
+ * @param[in] *pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] *pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1.
+ * @return none.
+ */
+
+ void arm_correlate_q31(
+ q31_t * pSrcA,
+ uint32_t srcALen,
+ q31_t * pSrcB,
+ uint32_t srcBLen,
+ q31_t * pDst);
+
+ /**
+ * @brief Correlation of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4
+ * @param[in] *pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] *pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1.
+ * @return none.
+ */
+
+ void arm_correlate_fast_q31(
+ q31_t * pSrcA,
+ uint32_t srcALen,
+ q31_t * pSrcB,
+ uint32_t srcBLen,
+ q31_t * pDst);
+
+ /**
+ * @brief Correlation of Q7 sequences.
+ * @param[in] *pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] *pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1.
+ * @return none.
+ */
+
+ void arm_correlate_q7(
+ q7_t * pSrcA,
+ uint32_t srcALen,
+ q7_t * pSrcB,
+ uint32_t srcBLen,
+ q7_t * pDst);
+
+ /**
+ * @brief Instance structure for the floating-point sparse FIR filter.
+ */
+ typedef struct
+ {
+ uint16_t numTaps; /**< number of coefficients in the filter. */
+ uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */
+ float32_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */
+ float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/
+ uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */
+ int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */
+ } arm_fir_sparse_instance_f32;
+
+ /**
+ * @brief Instance structure for the Q31 sparse FIR filter.
+ */
+
+ typedef struct
+ {
+ uint16_t numTaps; /**< number of coefficients in the filter. */
+ uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */
+ q31_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */
+ q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/
+ uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */
+ int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */
+ } arm_fir_sparse_instance_q31;
+
+ /**
+ * @brief Instance structure for the Q15 sparse FIR filter.
+ */
+
+ typedef struct
+ {
+ uint16_t numTaps; /**< number of coefficients in the filter. */
+ uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */
+ q15_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */
+ q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/
+ uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */
+ int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */
+ } arm_fir_sparse_instance_q15;
+
+ /**
+ * @brief Instance structure for the Q7 sparse FIR filter.
+ */
+
+ typedef struct
+ {
+ uint16_t numTaps; /**< number of coefficients in the filter. */
+ uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */
+ q7_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */
+ q7_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/
+ uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */
+ int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */
+ } arm_fir_sparse_instance_q7;
+
+ /**
+ * @brief Processing function for the floating-point sparse FIR filter.
+ * @param[in] *S points to an instance of the floating-point sparse FIR structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data
+ * @param[in] *pScratchIn points to a temporary buffer of size blockSize.
+ * @param[in] blockSize number of input samples to process per call.
+ * @return none.
+ */
+
+ void arm_fir_sparse_f32(
+ arm_fir_sparse_instance_f32 * S,
+ float32_t * pSrc,
+ float32_t * pDst,
+ float32_t * pScratchIn,
+ uint32_t blockSize);
+
+ /**
+ * @brief Initialization function for the floating-point sparse FIR filter.
+ * @param[in,out] *S points to an instance of the floating-point sparse FIR structure.
+ * @param[in] numTaps number of nonzero coefficients in the filter.
+ * @param[in] *pCoeffs points to the array of filter coefficients.
+ * @param[in] *pState points to the state buffer.
+ * @param[in] *pTapDelay points to the array of offset times.
+ * @param[in] maxDelay maximum offset time supported.
+ * @param[in] blockSize number of samples that will be processed per block.
+ * @return none
+ */
+
+ void arm_fir_sparse_init_f32(
+ arm_fir_sparse_instance_f32 * S,
+ uint16_t numTaps,
+ float32_t * pCoeffs,
+ float32_t * pState,
+ int32_t * pTapDelay,
+ uint16_t maxDelay,
+ uint32_t blockSize);
+
+ /**
+ * @brief Processing function for the Q31 sparse FIR filter.
+ * @param[in] *S points to an instance of the Q31 sparse FIR structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data
+ * @param[in] *pScratchIn points to a temporary buffer of size blockSize.
+ * @param[in] blockSize number of input samples to process per call.
+ * @return none.
+ */
+
+ void arm_fir_sparse_q31(
+ arm_fir_sparse_instance_q31 * S,
+ q31_t * pSrc,
+ q31_t * pDst,
+ q31_t * pScratchIn,
+ uint32_t blockSize);
+
+ /**
+ * @brief Initialization function for the Q31 sparse FIR filter.
+ * @param[in,out] *S points to an instance of the Q31 sparse FIR structure.
+ * @param[in] numTaps number of nonzero coefficients in the filter.
+ * @param[in] *pCoeffs points to the array of filter coefficients.
+ * @param[in] *pState points to the state buffer.
+ * @param[in] *pTapDelay points to the array of offset times.
+ * @param[in] maxDelay maximum offset time supported.
+ * @param[in] blockSize number of samples that will be processed per block.
+ * @return none
+ */
+
+ void arm_fir_sparse_init_q31(
+ arm_fir_sparse_instance_q31 * S,
+ uint16_t numTaps,
+ q31_t * pCoeffs,
+ q31_t * pState,
+ int32_t * pTapDelay,
+ uint16_t maxDelay,
+ uint32_t blockSize);
+
+ /**
+ * @brief Processing function for the Q15 sparse FIR filter.
+ * @param[in] *S points to an instance of the Q15 sparse FIR structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data
+ * @param[in] *pScratchIn points to a temporary buffer of size blockSize.
+ * @param[in] *pScratchOut points to a temporary buffer of size blockSize.
+ * @param[in] blockSize number of input samples to process per call.
+ * @return none.
+ */
+
+ void arm_fir_sparse_q15(
+ arm_fir_sparse_instance_q15 * S,
+ q15_t * pSrc,
+ q15_t * pDst,
+ q15_t * pScratchIn,
+ q31_t * pScratchOut,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for the Q15 sparse FIR filter.
+ * @param[in,out] *S points to an instance of the Q15 sparse FIR structure.
+ * @param[in] numTaps number of nonzero coefficients in the filter.
+ * @param[in] *pCoeffs points to the array of filter coefficients.
+ * @param[in] *pState points to the state buffer.
+ * @param[in] *pTapDelay points to the array of offset times.
+ * @param[in] maxDelay maximum offset time supported.
+ * @param[in] blockSize number of samples that will be processed per block.
+ * @return none
+ */
+
+ void arm_fir_sparse_init_q15(
+ arm_fir_sparse_instance_q15 * S,
+ uint16_t numTaps,
+ q15_t * pCoeffs,
+ q15_t * pState,
+ int32_t * pTapDelay,
+ uint16_t maxDelay,
+ uint32_t blockSize);
+
+ /**
+ * @brief Processing function for the Q7 sparse FIR filter.
+ * @param[in] *S points to an instance of the Q7 sparse FIR structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data
+ * @param[in] *pScratchIn points to a temporary buffer of size blockSize.
+ * @param[in] *pScratchOut points to a temporary buffer of size blockSize.
+ * @param[in] blockSize number of input samples to process per call.
+ * @return none.
+ */
+
+ void arm_fir_sparse_q7(
+ arm_fir_sparse_instance_q7 * S,
+ q7_t * pSrc,
+ q7_t * pDst,
+ q7_t * pScratchIn,
+ q31_t * pScratchOut,
+ uint32_t blockSize);
+
+ /**
+ * @brief Initialization function for the Q7 sparse FIR filter.
+ * @param[in,out] *S points to an instance of the Q7 sparse FIR structure.
+ * @param[in] numTaps number of nonzero coefficients in the filter.
+ * @param[in] *pCoeffs points to the array of filter coefficients.
+ * @param[in] *pState points to the state buffer.
+ * @param[in] *pTapDelay points to the array of offset times.
+ * @param[in] maxDelay maximum offset time supported.
+ * @param[in] blockSize number of samples that will be processed per block.
+ * @return none
+ */
+
+ void arm_fir_sparse_init_q7(
+ arm_fir_sparse_instance_q7 * S,
+ uint16_t numTaps,
+ q7_t * pCoeffs,
+ q7_t * pState,
+ int32_t *pTapDelay,
+ uint16_t maxDelay,
+ uint32_t blockSize);
+
+
+ /*
+ * @brief Floating-point sin_cos function.
+ * @param[in] theta input value in degrees
+ * @param[out] *pSinVal points to the processed sine output.
+ * @param[out] *pCosVal points to the processed cos output.
+ * @return none.
+ */
+
+ void arm_sin_cos_f32(
+ float32_t theta,
+ float32_t *pSinVal,
+ float32_t *pCcosVal);
+
+ /*
+ * @brief Q31 sin_cos function.
+ * @param[in] theta scaled input value in degrees
+ * @param[out] *pSinVal points to the processed sine output.
+ * @param[out] *pCosVal points to the processed cosine output.
+ * @return none.
+ */
+
+ void arm_sin_cos_q31(
+ q31_t theta,
+ q31_t *pSinVal,
+ q31_t *pCosVal);
+
+
+ /**
+ * @brief Floating-point complex conjugate.
+ * @param[in] *pSrc points to the input vector
+ * @param[out] *pDst points to the output vector
+ * @param[in] numSamples number of complex samples in each vector
+ * @return none.
+ */
+
+ void arm_cmplx_conj_f32(
+ float32_t * pSrc,
+ float32_t * pDst,
+ uint32_t numSamples);
+
+ /**
+ * @brief Q31 complex conjugate.
+ * @param[in] *pSrc points to the input vector
+ * @param[out] *pDst points to the output vector
+ * @param[in] numSamples number of complex samples in each vector
+ * @return none.
+ */
+
+ void arm_cmplx_conj_q31(
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t numSamples);
+
+ /**
+ * @brief Q15 complex conjugate.
+ * @param[in] *pSrc points to the input vector
+ * @param[out] *pDst points to the output vector
+ * @param[in] numSamples number of complex samples in each vector
+ * @return none.
+ */
+
+ void arm_cmplx_conj_q15(
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t numSamples);
+
+
+
+ /**
+ * @brief Floating-point complex magnitude squared
+ * @param[in] *pSrc points to the complex input vector
+ * @param[out] *pDst points to the real output vector
+ * @param[in] numSamples number of complex samples in the input vector
+ * @return none.
+ */
+
+ void arm_cmplx_mag_squared_f32(
+ float32_t * pSrc,
+ float32_t * pDst,
+ uint32_t numSamples);
+
+ /**
+ * @brief Q31 complex magnitude squared
+ * @param[in] *pSrc points to the complex input vector
+ * @param[out] *pDst points to the real output vector
+ * @param[in] numSamples number of complex samples in the input vector
+ * @return none.
+ */
+
+ void arm_cmplx_mag_squared_q31(
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t numSamples);
+
+ /**
+ * @brief Q15 complex magnitude squared
+ * @param[in] *pSrc points to the complex input vector
+ * @param[out] *pDst points to the real output vector
+ * @param[in] numSamples number of complex samples in the input vector
+ * @return none.
+ */
+
+ void arm_cmplx_mag_squared_q15(
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t numSamples);
+
+
+ /**
+ * @ingroup groupController
+ */
+
+ /**
+ * @defgroup PID PID Motor Control
+ *
+ * A Proportional Integral Derivative (PID) controller is a generic feedback control
+ * loop mechanism widely used in industrial control systems.
+ * A PID controller is the most commonly used type of feedback controller.
+ *
+ * This set of functions implements (PID) controllers
+ * for Q15, Q31, and floating-point data types. The functions operate on a single sample
+ * of data and each call to the function returns a single processed value.
+ * S points to an instance of the PID control data structure. in
+ * is the input sample value. The functions return the output value.
+ *
+ * \par Algorithm:
+ *
+ *
+ * \par
+ * where \c Kp is proportional constant, \c Ki is Integral constant and \c Kd is Derivative constant
+ *
+ * \par
+ * \image html PID.gif "Proportional Integral Derivative Controller"
+ *
+ * \par
+ * The PID controller calculates an "error" value as the difference between
+ * the measured output and the reference input.
+ * The controller attempts to minimize the error by adjusting the process control inputs.
+ * The proportional value determines the reaction to the current error,
+ * the integral value determines the reaction based on the sum of recent errors,
+ * and the derivative value determines the reaction based on the rate at which the error has been changing.
+ *
+ * \par Instance Structure
+ * The Gains A0, A1, A2 and state variables for a PID controller are stored together in an instance data structure.
+ * A separate instance structure must be defined for each PID Controller.
+ * There are separate instance structure declarations for each of the 3 supported data types.
+ *
+ * \par Reset Functions
+ * There is also an associated reset function for each data type which clears the state array.
+ *
+ * \par Initialization Functions
+ * There is also an associated initialization function for each data type.
+ * The initialization function performs the following operations:
+ * - Initializes the Gains A0, A1, A2 from Kp,Ki, Kd gains.
+ * - Zeros out the values in the state buffer.
+ *
+ * \par
+ * Instance structure cannot be placed into a const data section and it is recommended to use the initialization function.
+ *
+ * \par Fixed-Point Behavior
+ * Care must be taken when using the fixed-point versions of the PID Controller functions.
+ * In particular, the overflow and saturation behavior of the accumulator used in each function must be considered.
+ * Refer to the function specific documentation below for usage guidelines.
+ */
+
+ /**
+ * @addtogroup PID
+ * @{
+ */
+
+ /**
+ * @brief Process function for the floating-point PID Control.
+ * @param[in,out] *S is an instance of the floating-point PID Control structure
+ * @param[in] in input sample to process
+ * @return out processed output sample.
+ */
+
+
+ static __INLINE float32_t arm_pid_f32(
+ arm_pid_instance_f32 * S,
+ float32_t in)
+ {
+ float32_t out;
+
+ /* y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2] */
+ out = (S->A0 * in) +
+ (S->A1 * S->state[0]) + (S->A2 * S->state[1]) + (S->state[2]);
+
+ /* Update state */
+ S->state[1] = S->state[0];
+ S->state[0] = in;
+ S->state[2] = out;
+
+ /* return to application */
+ return (out);
+
+ }
+
+ /**
+ * @brief Process function for the Q31 PID Control.
+ * @param[in,out] *S points to an instance of the Q31 PID Control structure
+ * @param[in] in input sample to process
+ * @return out processed output sample.
+ *
+ * Scaling and Overflow Behavior:
+ * \par
+ * The function is implemented using an internal 64-bit accumulator.
+ * The accumulator has a 2.62 format and maintains full precision of the intermediate multiplication results but provides only a single guard bit.
+ * Thus, if the accumulator result overflows it wraps around rather than clip.
+ * In order to avoid overflows completely the input signal must be scaled down by 2 bits as there are four additions.
+ * After all multiply-accumulates are performed, the 2.62 accumulator is truncated to 1.32 format and then saturated to 1.31 format.
+ */
+
+ static __INLINE q31_t arm_pid_q31(
+ arm_pid_instance_q31 * S,
+ q31_t in)
+ {
+ q63_t acc;
+ q31_t out;
+
+ /* acc = A0 * x[n] */
+ acc = (q63_t) S->A0 * in;
+
+ /* acc += A1 * x[n-1] */
+ acc += (q63_t) S->A1 * S->state[0];
+
+ /* acc += A2 * x[n-2] */
+ acc += (q63_t) S->A2 * S->state[1];
+
+ /* convert output to 1.31 format to add y[n-1] */
+ out = (q31_t) (acc >> 31u);
+
+ /* out += y[n-1] */
+ out += S->state[2];
+
+ /* Update state */
+ S->state[1] = S->state[0];
+ S->state[0] = in;
+ S->state[2] = out;
+
+ /* return to application */
+ return (out);
+
+ }
+
+ /**
+ * @brief Process function for the Q15 PID Control.
+ * @param[in,out] *S points to an instance of the Q15 PID Control structure
+ * @param[in] in input sample to process
+ * @return out processed output sample.
+ *
+ * Scaling and Overflow Behavior:
+ * \par
+ * The function is implemented using a 64-bit internal accumulator.
+ * Both Gains and state variables are represented in 1.15 format and multiplications yield a 2.30 result.
+ * The 2.30 intermediate results are accumulated in a 64-bit accumulator in 34.30 format.
+ * There is no risk of internal overflow with this approach and the full precision of intermediate multiplications is preserved.
+ * After all additions have been performed, the accumulator is truncated to 34.15 format by discarding low 15 bits.
+ * Lastly, the accumulator is saturated to yield a result in 1.15 format.
+ */
+
+ static __INLINE q15_t arm_pid_q15(
+ arm_pid_instance_q15 * S,
+ q15_t in)
+ {
+ q63_t acc;
+ q15_t out;
+
+ /* Implementation of PID controller */
+
+ #ifdef ARM_MATH_CM0
+
+ /* acc = A0 * x[n] */
+ acc = ((q31_t) S->A0 )* in ;
+
+ #else
+
+ /* acc = A0 * x[n] */
+ acc = (q31_t) __SMUAD(S->A0, in);
+
+ #endif
+
+ #ifdef ARM_MATH_CM0
+
+ /* acc += A1 * x[n-1] + A2 * x[n-2] */
+ acc += (q31_t) S->A1 * S->state[0] ;
+ acc += (q31_t) S->A2 * S->state[1] ;
+
+ #else
+
+ /* acc += A1 * x[n-1] + A2 * x[n-2] */
+ acc = __SMLALD(S->A1, (q31_t)__SIMD32(S->state), acc);
+
+ #endif
+
+ /* acc += y[n-1] */
+ acc += (q31_t) S->state[2] << 15;
+
+ /* saturate the output */
+ out = (q15_t) (__SSAT((acc >> 15), 16));
+
+ /* Update state */
+ S->state[1] = S->state[0];
+ S->state[0] = in;
+ S->state[2] = out;
+
+ /* return to application */
+ return (out);
+
+ }
+
+ /**
+ * @} end of PID group
+ */
+
+
+ /**
+ * @brief Floating-point matrix inverse.
+ * @param[in] *src points to the instance of the input floating-point matrix structure.
+ * @param[out] *dst points to the instance of the output floating-point matrix structure.
+ * @return The function returns ARM_MATH_SIZE_MISMATCH, if the dimensions do not match.
+ * If the input matrix is singular (does not have an inverse), then the algorithm terminates and returns error status ARM_MATH_SINGULAR.
+ */
+
+ arm_status arm_mat_inverse_f32(
+ const arm_matrix_instance_f32 * src,
+ arm_matrix_instance_f32 * dst);
+
+
+
+ /**
+ * @ingroup groupController
+ */
+
+
+ /**
+ * @defgroup clarke Vector Clarke Transform
+ * Forward Clarke transform converts the instantaneous stator phases into a two-coordinate time invariant vector.
+ * Generally the Clarke transform uses three-phase currents Ia, Ib and Ic to calculate currents
+ * in the two-phase orthogonal stator axis Ialpha and Ibeta.
+ * When Ialpha is superposed with Ia as shown in the figure below
+ * \image html clarke.gif Stator current space vector and its components in (a,b).
+ * and Ia + Ib + Ic = 0, in this condition Ialpha and Ibeta
+ * can be calculated using only Ia and Ib.
+ *
+ * The function operates on a single sample of data and each call to the function returns the processed output.
+ * The library provides separate functions for Q31 and floating-point data types.
+ * \par Algorithm
+ * \image html clarkeFormula.gif
+ * where Ia and Ib are the instantaneous stator phases and
+ * pIalpha and pIbeta are the two coordinates of time invariant vector.
+ * \par Fixed-Point Behavior
+ * Care must be taken when using the Q31 version of the Clarke transform.
+ * In particular, the overflow and saturation behavior of the accumulator used must be considered.
+ * Refer to the function specific documentation below for usage guidelines.
+ */
+
+ /**
+ * @addtogroup clarke
+ * @{
+ */
+
+ /**
+ *
+ * @brief Floating-point Clarke transform
+ * @param[in] Ia input three-phase coordinate a
+ * @param[in] Ib input three-phase coordinate b
+ * @param[out] *pIalpha points to output two-phase orthogonal vector axis alpha
+ * @param[out] *pIbeta points to output two-phase orthogonal vector axis beta
+ * @return none.
+ */
+
+ static __INLINE void arm_clarke_f32(
+ float32_t Ia,
+ float32_t Ib,
+ float32_t * pIalpha,
+ float32_t * pIbeta)
+ {
+ /* Calculate pIalpha using the equation, pIalpha = Ia */
+ *pIalpha = Ia;
+
+ /* Calculate pIbeta using the equation, pIbeta = (1/sqrt(3)) * Ia + (2/sqrt(3)) * Ib */
+ *pIbeta = ((float32_t) 0.57735026919 * Ia + (float32_t) 1.15470053838 * Ib);
+
+ }
+
+ /**
+ * @brief Clarke transform for Q31 version
+ * @param[in] Ia input three-phase coordinate a
+ * @param[in] Ib input three-phase coordinate b
+ * @param[out] *pIalpha points to output two-phase orthogonal vector axis alpha
+ * @param[out] *pIbeta points to output two-phase orthogonal vector axis beta
+ * @return none.
+ *
+ * Scaling and Overflow Behavior:
+ * \par
+ * The function is implemented using an internal 32-bit accumulator.
+ * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format.
+ * There is saturation on the addition, hence there is no risk of overflow.
+ */
+
+ static __INLINE void arm_clarke_q31(
+ q31_t Ia,
+ q31_t Ib,
+ q31_t * pIalpha,
+ q31_t * pIbeta)
+ {
+ q31_t product1, product2; /* Temporary variables used to store intermediate results */
+
+ /* Calculating pIalpha from Ia by equation pIalpha = Ia */
+ *pIalpha = Ia;
+
+ /* Intermediate product is calculated by (1/(sqrt(3)) * Ia) */
+ product1 = (q31_t) (((q63_t) Ia * 0x24F34E8B) >> 30);
+
+ /* Intermediate product is calculated by (2/sqrt(3) * Ib) */
+ product2 = (q31_t) (((q63_t) Ib * 0x49E69D16) >> 30);
+
+ /* pIbeta is calculated by adding the intermediate products */
+ *pIbeta = __QADD(product1, product2);
+ }
+
+ /**
+ * @} end of clarke group
+ */
+
+ /**
+ * @brief Converts the elements of the Q7 vector to Q31 vector.
+ * @param[in] *pSrc input pointer
+ * @param[out] *pDst output pointer
+ * @param[in] blockSize number of samples to process
+ * @return none.
+ */
+ void arm_q7_to_q31(
+ q7_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+
+
+
+ /**
+ * @ingroup groupController
+ */
+
+ /**
+ * @defgroup inv_clarke Vector Inverse Clarke Transform
+ * Inverse Clarke transform converts the two-coordinate time invariant vector into instantaneous stator phases.
+ *
+ * The function operates on a single sample of data and each call to the function returns the processed output.
+ * The library provides separate functions for Q31 and floating-point data types.
+ * \par Algorithm
+ * \image html clarkeInvFormula.gif
+ * where pIa and pIb are the instantaneous stator phases and
+ * Ialpha and Ibeta are the two coordinates of time invariant vector.
+ * \par Fixed-Point Behavior
+ * Care must be taken when using the Q31 version of the Clarke transform.
+ * In particular, the overflow and saturation behavior of the accumulator used must be considered.
+ * Refer to the function specific documentation below for usage guidelines.
+ */
+
+ /**
+ * @addtogroup inv_clarke
+ * @{
+ */
+
+ /**
+ * @brief Floating-point Inverse Clarke transform
+ * @param[in] Ialpha input two-phase orthogonal vector axis alpha
+ * @param[in] Ibeta input two-phase orthogonal vector axis beta
+ * @param[out] *pIa points to output three-phase coordinate a
+ * @param[out] *pIb points to output three-phase coordinate b
+ * @return none.
+ */
+
+
+ static __INLINE void arm_inv_clarke_f32(
+ float32_t Ialpha,
+ float32_t Ibeta,
+ float32_t * pIa,
+ float32_t * pIb)
+ {
+ /* Calculating pIa from Ialpha by equation pIa = Ialpha */
+ *pIa = Ialpha;
+
+ /* Calculating pIb from Ialpha and Ibeta by equation pIb = -(1/2) * Ialpha + (sqrt(3)/2) * Ibeta */
+ *pIb = -0.5 * Ialpha + (float32_t) 0.8660254039 *Ibeta;
+
+ }
+
+ /**
+ * @brief Inverse Clarke transform for Q31 version
+ * @param[in] Ialpha input two-phase orthogonal vector axis alpha
+ * @param[in] Ibeta input two-phase orthogonal vector axis beta
+ * @param[out] *pIa points to output three-phase coordinate a
+ * @param[out] *pIb points to output three-phase coordinate b
+ * @return none.
+ *
+ * Scaling and Overflow Behavior:
+ * \par
+ * The function is implemented using an internal 32-bit accumulator.
+ * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format.
+ * There is saturation on the subtraction, hence there is no risk of overflow.
+ */
+
+ static __INLINE void arm_inv_clarke_q31(
+ q31_t Ialpha,
+ q31_t Ibeta,
+ q31_t * pIa,
+ q31_t * pIb)
+ {
+ q31_t product1, product2; /* Temporary variables used to store intermediate results */
+
+ /* Calculating pIa from Ialpha by equation pIa = Ialpha */
+ *pIa = Ialpha;
+
+ /* Intermediate product is calculated by (1/(2*sqrt(3)) * Ia) */
+ product1 = (q31_t) (((q63_t) (Ialpha) * (0x40000000)) >> 31);
+
+ /* Intermediate product is calculated by (1/sqrt(3) * pIb) */
+ product2 = (q31_t) (((q63_t) (Ibeta) * (0x6ED9EBA1)) >> 31);
+
+ /* pIb is calculated by subtracting the products */
+ *pIb = __QSUB(product2, product1);
+
+ }
+
+ /**
+ * @} end of inv_clarke group
+ */
+
+ /**
+ * @brief Converts the elements of the Q7 vector to Q15 vector.
+ * @param[in] *pSrc input pointer
+ * @param[out] *pDst output pointer
+ * @param[in] blockSize number of samples to process
+ * @return none.
+ */
+ void arm_q7_to_q15(
+ q7_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+
+
+ /**
+ * @ingroup groupController
+ */
+
+ /**
+ * @defgroup park Vector Park Transform
+ *
+ * Forward Park transform converts the input two-coordinate vector to flux and torque components.
+ * The Park transform can be used to realize the transformation of the Ialpha and the Ibeta currents
+ * from the stationary to the moving reference frame and control the spatial relationship between
+ * the stator vector current and rotor flux vector.
+ * If we consider the d axis aligned with the rotor flux, the diagram below shows the
+ * current vector and the relationship from the two reference frames:
+ * \image html park.gif "Stator current space vector and its component in (a,b) and in the d,q rotating reference frame"
+ *
+ * The function operates on a single sample of data and each call to the function returns the processed output.
+ * The library provides separate functions for Q31 and floating-point data types.
+ * \par Algorithm
+ * \image html parkFormula.gif
+ * where Ialpha and Ibeta are the stator vector components,
+ * pId and pIq are rotor vector components and cosVal and sinVal are the
+ * cosine and sine values of theta (rotor flux position).
+ * \par Fixed-Point Behavior
+ * Care must be taken when using the Q31 version of the Park transform.
+ * In particular, the overflow and saturation behavior of the accumulator used must be considered.
+ * Refer to the function specific documentation below for usage guidelines.
+ */
+
+ /**
+ * @addtogroup park
+ * @{
+ */
+
+ /**
+ * @brief Floating-point Park transform
+ * @param[in] Ialpha input two-phase vector coordinate alpha
+ * @param[in] Ibeta input two-phase vector coordinate beta
+ * @param[out] *pId points to output rotor reference frame d
+ * @param[out] *pIq points to output rotor reference frame q
+ * @param[in] sinVal sine value of rotation angle theta
+ * @param[in] cosVal cosine value of rotation angle theta
+ * @return none.
+ *
+ * The function implements the forward Park transform.
+ *
+ */
+
+ static __INLINE void arm_park_f32(
+ float32_t Ialpha,
+ float32_t Ibeta,
+ float32_t * pId,
+ float32_t * pIq,
+ float32_t sinVal,
+ float32_t cosVal)
+ {
+ /* Calculate pId using the equation, pId = Ialpha * cosVal + Ibeta * sinVal */
+ *pId = Ialpha * cosVal + Ibeta * sinVal;
+
+ /* Calculate pIq using the equation, pIq = - Ialpha * sinVal + Ibeta * cosVal */
+ *pIq = -Ialpha * sinVal + Ibeta * cosVal;
+
+ }
+
+ /**
+ * @brief Park transform for Q31 version
+ * @param[in] Ialpha input two-phase vector coordinate alpha
+ * @param[in] Ibeta input two-phase vector coordinate beta
+ * @param[out] *pId points to output rotor reference frame d
+ * @param[out] *pIq points to output rotor reference frame q
+ * @param[in] sinVal sine value of rotation angle theta
+ * @param[in] cosVal cosine value of rotation angle theta
+ * @return none.
+ *
+ * Scaling and Overflow Behavior:
+ * \par
+ * The function is implemented using an internal 32-bit accumulator.
+ * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format.
+ * There is saturation on the addition and subtraction, hence there is no risk of overflow.
+ */
+
+
+ static __INLINE void arm_park_q31(
+ q31_t Ialpha,
+ q31_t Ibeta,
+ q31_t * pId,
+ q31_t * pIq,
+ q31_t sinVal,
+ q31_t cosVal)
+ {
+ q31_t product1, product2; /* Temporary variables used to store intermediate results */
+ q31_t product3, product4; /* Temporary variables used to store intermediate results */
+
+ /* Intermediate product is calculated by (Ialpha * cosVal) */
+ product1 = (q31_t) (((q63_t) (Ialpha) * (cosVal)) >> 31);
+
+ /* Intermediate product is calculated by (Ibeta * sinVal) */
+ product2 = (q31_t) (((q63_t) (Ibeta) * (sinVal)) >> 31);
+
+
+ /* Intermediate product is calculated by (Ialpha * sinVal) */
+ product3 = (q31_t) (((q63_t) (Ialpha) * (sinVal)) >> 31);
+
+ /* Intermediate product is calculated by (Ibeta * cosVal) */
+ product4 = (q31_t) (((q63_t) (Ibeta) * (cosVal)) >> 31);
+
+ /* Calculate pId by adding the two intermediate products 1 and 2 */
+ *pId = __QADD(product1, product2);
+
+ /* Calculate pIq by subtracting the two intermediate products 3 from 4 */
+ *pIq = __QSUB(product4, product3);
+ }
+
+ /**
+ * @} end of park group
+ */
+
+ /**
+ * @brief Converts the elements of the Q7 vector to floating-point vector.
+ * @param[in] *pSrc is input pointer
+ * @param[out] *pDst is output pointer
+ * @param[in] blockSize is the number of samples to process
+ * @return none.
+ */
+ void arm_q7_to_float(
+ q7_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @ingroup groupController
+ */
+
+ /**
+ * @defgroup inv_park Vector Inverse Park transform
+ * Inverse Park transform converts the input flux and torque components to two-coordinate vector.
+ *
+ * The function operates on a single sample of data and each call to the function returns the processed output.
+ * The library provides separate functions for Q31 and floating-point data types.
+ * \par Algorithm
+ * \image html parkInvFormula.gif
+ * where pIalpha and pIbeta are the stator vector components,
+ * Id and Iq are rotor vector components and cosVal and sinVal are the
+ * cosine and sine values of theta (rotor flux position).
+ * \par Fixed-Point Behavior
+ * Care must be taken when using the Q31 version of the Park transform.
+ * In particular, the overflow and saturation behavior of the accumulator used must be considered.
+ * Refer to the function specific documentation below for usage guidelines.
+ */
+
+ /**
+ * @addtogroup inv_park
+ * @{
+ */
+
+ /**
+ * @brief Floating-point Inverse Park transform
+ * @param[in] Id input coordinate of rotor reference frame d
+ * @param[in] Iq input coordinate of rotor reference frame q
+ * @param[out] *pIalpha points to output two-phase orthogonal vector axis alpha
+ * @param[out] *pIbeta points to output two-phase orthogonal vector axis beta
+ * @param[in] sinVal sine value of rotation angle theta
+ * @param[in] cosVal cosine value of rotation angle theta
+ * @return none.
+ */
+
+ static __INLINE void arm_inv_park_f32(
+ float32_t Id,
+ float32_t Iq,
+ float32_t * pIalpha,
+ float32_t * pIbeta,
+ float32_t sinVal,
+ float32_t cosVal)
+ {
+ /* Calculate pIalpha using the equation, pIalpha = Id * cosVal - Iq * sinVal */
+ *pIalpha = Id * cosVal - Iq * sinVal;
+
+ /* Calculate pIbeta using the equation, pIbeta = Id * sinVal + Iq * cosVal */
+ *pIbeta = Id * sinVal + Iq * cosVal;
+
+ }
+
+
+ /**
+ * @brief Inverse Park transform for Q31 version
+ * @param[in] Id input coordinate of rotor reference frame d
+ * @param[in] Iq input coordinate of rotor reference frame q
+ * @param[out] *pIalpha points to output two-phase orthogonal vector axis alpha
+ * @param[out] *pIbeta points to output two-phase orthogonal vector axis beta
+ * @param[in] sinVal sine value of rotation angle theta
+ * @param[in] cosVal cosine value of rotation angle theta
+ * @return none.
+ *
+ * Scaling and Overflow Behavior:
+ * \par
+ * The function is implemented using an internal 32-bit accumulator.
+ * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format.
+ * There is saturation on the addition, hence there is no risk of overflow.
+ */
+
+
+ static __INLINE void arm_inv_park_q31(
+ q31_t Id,
+ q31_t Iq,
+ q31_t * pIalpha,
+ q31_t * pIbeta,
+ q31_t sinVal,
+ q31_t cosVal)
+ {
+ q31_t product1, product2; /* Temporary variables used to store intermediate results */
+ q31_t product3, product4; /* Temporary variables used to store intermediate results */
+
+ /* Intermediate product is calculated by (Id * cosVal) */
+ product1 = (q31_t) (((q63_t) (Id) * (cosVal)) >> 31);
+
+ /* Intermediate product is calculated by (Iq * sinVal) */
+ product2 = (q31_t) (((q63_t) (Iq) * (sinVal)) >> 31);
+
+
+ /* Intermediate product is calculated by (Id * sinVal) */
+ product3 = (q31_t) (((q63_t) (Id) * (sinVal)) >> 31);
+
+ /* Intermediate product is calculated by (Iq * cosVal) */
+ product4 = (q31_t) (((q63_t) (Iq) * (cosVal)) >> 31);
+
+ /* Calculate pIalpha by using the two intermediate products 1 and 2 */
+ *pIalpha = __QSUB(product1, product2);
+
+ /* Calculate pIbeta by using the two intermediate products 3 and 4 */
+ *pIbeta = __QADD(product4, product3);
+
+ }
+
+ /**
+ * @} end of Inverse park group
+ */
+
+
+ /**
+ * @brief Converts the elements of the Q31 vector to floating-point vector.
+ * @param[in] *pSrc is input pointer
+ * @param[out] *pDst is output pointer
+ * @param[in] blockSize is the number of samples to process
+ * @return none.
+ */
+ void arm_q31_to_float(
+ q31_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @ingroup groupInterpolation
+ */
+
+ /**
+ * @defgroup LinearInterpolate Linear Interpolation
+ *
+ * Linear interpolation is a method of curve fitting using linear polynomials.
+ * Linear interpolation works by effectively drawing a straight line between two neighboring samples and returning the appropriate point along that line
+ *
+ * \par
+ * \image html LinearInterp.gif "Linear interpolation"
+ *
+ * \par
+ * A Linear Interpolate function calculates an output value(y), for the input(x)
+ * using linear interpolation of the input values x0, x1( nearest input values) and the output values y0 and y1(nearest output values)
+ *
+ * \par Algorithm:
+ *
+ * y = y0 + (x - x0) * ((y1 - y0)/(x1-x0))
+ * where x0, x1 are nearest values of input x
+ * y0, y1 are nearest values to output y
+ *
+ *
+ * \par
+ * This set of functions implements Linear interpolation process
+ * for Q7, Q15, Q31, and floating-point data types. The functions operate on a single
+ * sample of data and each call to the function returns a single processed value.
+ * S points to an instance of the Linear Interpolate function data structure.
+ * x is the input sample value. The functions returns the output value.
+ *
+ * \par
+ * if x is outside of the table boundary, Linear interpolation returns first value of the table
+ * if x is below input range and returns last value of table if x is above range.
+ */
+
+ /**
+ * @addtogroup LinearInterpolate
+ * @{
+ */
+
+ /**
+ * @brief Process function for the floating-point Linear Interpolation Function.
+ * @param[in,out] *S is an instance of the floating-point Linear Interpolation structure
+ * @param[in] x input sample to process
+ * @return y processed output sample.
+ *
+ */
+
+ static __INLINE float32_t arm_linear_interp_f32(
+ arm_linear_interp_instance_f32 * S,
+ float32_t x)
+ {
+
+ float32_t y;
+ float32_t x0, x1; /* Nearest input values */
+ float32_t y0, y1; /* Nearest output values */
+ float32_t xSpacing = S->xSpacing; /* spacing between input values */
+ int32_t i; /* Index variable */
+ float32_t *pYData = S->pYData; /* pointer to output table */
+
+ /* Calculation of index */
+ i = (x - S->x1) / xSpacing;
+
+ if(i < 0)
+ {
+ /* Iniatilize output for below specified range as least output value of table */
+ y = pYData[0];
+ }
+ else if(i >= S->nValues)
+ {
+ /* Iniatilize output for above specified range as last output value of table */
+ y = pYData[S->nValues-1];
+ }
+ else
+ {
+ /* Calculation of nearest input values */
+ x0 = S->x1 + i * xSpacing;
+ x1 = S->x1 + (i +1) * xSpacing;
+
+ /* Read of nearest output values */
+ y0 = pYData[i];
+ y1 = pYData[i + 1];
+
+ /* Calculation of output */
+ y = y0 + (x - x0) * ((y1 - y0)/(x1-x0));
+
+ }
+
+ /* returns output value */
+ return (y);
+ }
+
+ /**
+ *
+ * @brief Process function for the Q31 Linear Interpolation Function.
+ * @param[in] *pYData pointer to Q31 Linear Interpolation table
+ * @param[in] x input sample to process
+ * @param[in] nValues number of table values
+ * @return y processed output sample.
+ *
+ * \par
+ * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part.
+ * This function can support maximum of table size 2^12.
+ *
+ */
+
+
+ static __INLINE q31_t arm_linear_interp_q31(q31_t *pYData,
+ q31_t x, uint32_t nValues)
+ {
+ q31_t y; /* output */
+ q31_t y0, y1; /* Nearest output values */
+ q31_t fract; /* fractional part */
+ int32_t index; /* Index to read nearest output values */
+
+ /* Input is in 12.20 format */
+ /* 12 bits for the table index */
+ /* Index value calculation */
+ index = ((x & 0xFFF00000) >> 20);
+
+ if(index >= (nValues - 1))
+ {
+ return(pYData[nValues - 1]);
+ }
+ else if(index < 0)
+ {
+ return(pYData[0]);
+ }
+ else
+ {
+
+ /* 20 bits for the fractional part */
+ /* shift left by 11 to keep fract in 1.31 format */
+ fract = (x & 0x000FFFFF) << 11;
+
+ /* Read two nearest output values from the index in 1.31(q31) format */
+ y0 = pYData[index];
+ y1 = pYData[index + 1u];
+
+ /* Calculation of y0 * (1-fract) and y is in 2.30 format */
+ y = ((q31_t) ((q63_t) y0 * (0x7FFFFFFF - fract) >> 32));
+
+ /* Calculation of y0 * (1-fract) + y1 *fract and y is in 2.30 format */
+ y += ((q31_t) (((q63_t) y1 * fract) >> 32));
+
+ /* Convert y to 1.31 format */
+ return (y << 1u);
+
+ }
+
+ }
+
+ /**
+ *
+ * @brief Process function for the Q15 Linear Interpolation Function.
+ * @param[in] *pYData pointer to Q15 Linear Interpolation table
+ * @param[in] x input sample to process
+ * @param[in] nValues number of table values
+ * @return y processed output sample.
+ *
+ * \par
+ * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part.
+ * This function can support maximum of table size 2^12.
+ *
+ */
+
+
+ static __INLINE q15_t arm_linear_interp_q15(q15_t *pYData, q31_t x, uint32_t nValues)
+ {
+ q63_t y; /* output */
+ q15_t y0, y1; /* Nearest output values */
+ q31_t fract; /* fractional part */
+ int32_t index; /* Index to read nearest output values */
+
+ /* Input is in 12.20 format */
+ /* 12 bits for the table index */
+ /* Index value calculation */
+ index = ((x & 0xFFF00000) >> 20u);
+
+ if(index >= (nValues - 1))
+ {
+ return(pYData[nValues - 1]);
+ }
+ else if(index < 0)
+ {
+ return(pYData[0]);
+ }
+ else
+ {
+ /* 20 bits for the fractional part */
+ /* fract is in 12.20 format */
+ fract = (x & 0x000FFFFF);
+
+ /* Read two nearest output values from the index */
+ y0 = pYData[index];
+ y1 = pYData[index + 1u];
+
+ /* Calculation of y0 * (1-fract) and y is in 13.35 format */
+ y = ((q63_t) y0 * (0xFFFFF - fract));
+
+ /* Calculation of (y0 * (1-fract) + y1 * fract) and y is in 13.35 format */
+ y += ((q63_t) y1 * (fract));
+
+ /* convert y to 1.15 format */
+ return (y >> 20);
+ }
+
+
+ }
+
+ /**
+ *
+ * @brief Process function for the Q7 Linear Interpolation Function.
+ * @param[in] *pYData pointer to Q7 Linear Interpolation table
+ * @param[in] x input sample to process
+ * @param[in] nValues number of table values
+ * @return y processed output sample.
+ *
+ * \par
+ * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part.
+ * This function can support maximum of table size 2^12.
+ */
+
+
+ static __INLINE q7_t arm_linear_interp_q7(q7_t *pYData, q31_t x, uint32_t nValues)
+ {
+ q31_t y; /* output */
+ q7_t y0, y1; /* Nearest output values */
+ q31_t fract; /* fractional part */
+ int32_t index; /* Index to read nearest output values */
+
+ /* Input is in 12.20 format */
+ /* 12 bits for the table index */
+ /* Index value calculation */
+ index = ((x & 0xFFF00000) >> 20u);
+
+
+ if(index >= (nValues - 1))
+ {
+ return(pYData[nValues - 1]);
+ }
+ else if(index < 0)
+ {
+ return(pYData[0]);
+ }
+ else
+ {
+
+ /* 20 bits for the fractional part */
+ /* fract is in 12.20 format */
+ fract = (x & 0x000FFFFF);
+
+ /* Read two nearest output values from the index and are in 1.7(q7) format */
+ y0 = pYData[index];
+ y1 = pYData[index + 1u];
+
+ /* Calculation of y0 * (1-fract ) and y is in 13.27(q27) format */
+ y = ((y0 * (0xFFFFF - fract)));
+
+ /* Calculation of y1 * fract + y0 * (1-fract) and y is in 13.27(q27) format */
+ y += (y1 * fract);
+
+ /* convert y to 1.7(q7) format */
+ return (y >> 20u);
+
+ }
+
+ }
+ /**
+ * @} end of LinearInterpolate group
+ */
+
+ /**
+ * @brief Fast approximation to the trigonometric sine function for floating-point data.
+ * @param[in] x input value in radians.
+ * @return sin(x).
+ */
+
+ float32_t arm_sin_f32(
+ float32_t x);
+
+ /**
+ * @brief Fast approximation to the trigonometric sine function for Q31 data.
+ * @param[in] x Scaled input value in radians.
+ * @return sin(x).
+ */
+
+ q31_t arm_sin_q31(
+ q31_t x);
+
+ /**
+ * @brief Fast approximation to the trigonometric sine function for Q15 data.
+ * @param[in] x Scaled input value in radians.
+ * @return sin(x).
+ */
+
+ q15_t arm_sin_q15(
+ q15_t x);
+
+ /**
+ * @brief Fast approximation to the trigonometric cosine function for floating-point data.
+ * @param[in] x input value in radians.
+ * @return cos(x).
+ */
+
+ float32_t arm_cos_f32(
+ float32_t x);
+
+ /**
+ * @brief Fast approximation to the trigonometric cosine function for Q31 data.
+ * @param[in] x Scaled input value in radians.
+ * @return cos(x).
+ */
+
+ q31_t arm_cos_q31(
+ q31_t x);
+
+ /**
+ * @brief Fast approximation to the trigonometric cosine function for Q15 data.
+ * @param[in] x Scaled input value in radians.
+ * @return cos(x).
+ */
+
+ q15_t arm_cos_q15(
+ q15_t x);
+
+
+ /**
+ * @ingroup groupFastMath
+ */
+
+
+ /**
+ * @defgroup SQRT Square Root
+ *
+ * Computes the square root of a number.
+ * There are separate functions for Q15, Q31, and floating-point data types.
+ * The square root function is computed using the Newton-Raphson algorithm.
+ * This is an iterative algorithm of the form:
+ *
+ * x1 = x0 - f(x0)/f'(x0)
+ *
+ * where x1 is the current estimate,
+ * x0 is the previous estimate and
+ * f'(x0) is the derivative of f() evaluated at x0.
+ * For the square root function, the algorithm reduces to:
+ *
+ *
+ * \par
+ * where numRows specifies the number of rows in the table;
+ * numCols specifies the number of columns in the table;
+ * and pData points to an array of size numRows*numCols values.
+ * The data table pTable is organized in row order and the supplied data values fall on integer indexes.
+ * That is, table element (x,y) is located at pTable[x + y*numCols] where x and y are integers.
+ *
+ * \par
+ * Let (x, y) specify the desired interpolation point. Then define:
+ *
+ * XF = floor(x)
+ * YF = floor(y)
+ *
+ * \par
+ * The interpolated output point is computed as:
+ *
+
+
+
+
+
\ No newline at end of file
diff --git a/Libraries/README.md b/Libraries/README.md
new file mode 100644
index 0000000..3847c3a
--- /dev/null
+++ b/Libraries/README.md
@@ -0,0 +1,58 @@
+# ioLibrary Driver
+The ioLibrary means “Internet Offload Library” for WIZnet chip. It includes drivers and application protocols.
+The driver (ioLibrary) can be used for the application design of WIZnet TCP/IP chips as [W5500](http://wizwiki.net/wiki/doku.php?id=products:w5500:start), W5300, W5200, W5100 [W5100S](http://wizwiki.net/wiki/doku.php?id=products:w5100s:start).
+
+## ioLibrary
+This driver provides the Berkeley Socket type APIs.
+- Directory Structure
+
+
+
+- Ethernet : SOCKET APIs like BSD & WIZCHIP([W5500](http://wizwiki.net/wiki/doku.php?id=products:w5500:start) / W5300 / W5200 / W5100 / [W5100S](http://wizwiki.net/wiki/doku.php?id=products:w5100s:start)) Driver
+- Internet :
+ - DHCP client
+ - DNS client
+ - FTP client
+ - FTP server
+ - SNMP agent/trap
+ - SNTP client
+ - TFTP client
+ - HTTP server
+ - MQTT Client
+ - Others will be added.
+
+## How to add an ioLibrary in project through github site.
+ - Example, refer to https://www.youtube.com/watch?v=mt815RBGdsA
+ - [ioLibrary Doxygen doument](https://github.com/Wiznet/ioLibrary_Driver/blob/master/Ethernet/Socket_APIs_V3.0.3.chm) : Refer to **TODO** in this document
+ - Define what chip is used in **wizchip_conf.h**
+ - Define what Host I/F mode is used in **wizchip_conf.h**
+
+## Revision History
+ * ioLibrary V4.0.0 Released : 29, MAR, 2018
+ * New features added: Library for W5100S added.
+ * ioLibrary V3.1.1 Released : 14, Dec, 2016
+ * Bug fixed : In Socket.c Fixed MACraw & IPraw sendto function.
+ * ioLibrary V3.1.0 Released : 05, Dec, 2016
+ * Internet application protocol add to MQTT Client (using paho MQTT 3.11)
+ * ioLibrary V3.0.3 Released : 03, May, 2016
+ * In W5300, Fixed some compile errors in close(). Refer to M20160503
+ * In close(), replace socket() with some command sequences.
+ * ioLibrary V3.0.2 Released : 26, April, 2016
+ * Applied the erratum #1 in close() of socket.c (Refer to A20160426)
+ * ioLibrary V3.0.1 Released : 15, July, 2015
+ * Bug fixed : In W5100, Fixed CS control problem in read/write buffer with SPI. Refer to M20150715.
+ * ioLibrary V3.0 Released : 01, June, 2015
+ * Add to W5300
+ * Typing Error in comments
+ * Refer to 20150601 in sources.
+
+ * Type casting error Fixed : 09, April. 2015
+ In socket.c, send() : Refer to M20150409
+
+ * ioLibrary V2.0 released : April. 2015
+ * Added to W5100, W5200
+ * Correct to some typing error
+ * Fixed the warning of type casting.
+
+ * Last release : Nov. 2014
+
diff --git a/Libraries/STM32F10x_StdPeriph_Driver/Release_Notes.html b/Libraries/STM32F10x_StdPeriph_Driver/Release_Notes.html
new file mode 100644
index 0000000..8999a27
--- /dev/null
+++ b/Libraries/STM32F10x_StdPeriph_Driver/Release_Notes.html
@@ -0,0 +1,340 @@
+
+
+
+
+
+
+
+
+
+
+
+
+Release Notes for STM32F10x Standard Peripherals Library Drivers
+
+
+
+
+
+
STM32F10x Standard
+Peripherals Library Drivers update History
V3.6.1 / 05-March-2012
+
Main
+Changes
+
+
All source files: license disclaimer text update and add link to the License file on ST Internet.
V3.6.0 / 27-January-2012
Main
+Changes
+
All source files: update disclaimer to add reference to the new license agreement
stm32f10x_sdio.c
SDIO_SetPowerState() function: fix POWER register configuration, only one access (for read or write) is allowed
stm32f10x_usart.h/.c
Update procedure to check on overrun error interrupt pending bit, defines for the following flag are added:
USART_IT_ORE_RX: this flag is set if overrun error interrupt occurs and RXNEIE bit is set
USART_IT_ORE_ER:this flag is set if overrun error interrupt occurs and EIE bit is set
Remove IS_USART_PERIPH_FLAG macro (not used)
stm32f10x_rtc.c
Update RTC_GetCounter() function to fix issue when reading the RTC counter registers (CNTL & CNTH registers) and the counter rolls over
stm32f10x_flash.c
Flash keys moved from to stm32f10x.h file
stm32f10x_tim.c
TIM_UpdateRequestConfig(): correct function header's comment
stm32f10x_exti.h
EXTI_InitTypeDef structure : for “EXTI_Trigger“ member, change “@ref EXTIMode_TypeDef” by “@ref EXTITrigger_TypeDef”
+
V3.5.0 / 11-March-2011
+
Main
+Changes
+
+
+
stm32f10x_can.h/.c files:
+
+
Add 5 new functions
+
+
3
+new functions controlling the counter errors: CAN_GetLastErrorCode(),
+CAN_GetReceiveErrorCounter() and CAN_GetLSBTransmitErrorCounter().
+
+
+
1 new function to select the CAN operating mode: CAN_OperatingModeRequest().
+
+
+
1 new function to support CAN TT mode: CAN_TTComModeCmd().
+
+
+
CAN_TransmitStatus() function updated to support all CAN transmit intermediate states
+
+
+
stm32f10x_i2c.h/.c files:
+
+
Add 1 new function:
+
+
I2C_NACKPositionConfig():
+This function configures the same bit (POS) as I2C_PECPositionConfig()
+but is intended to be used in I2C mode while I2C_PECPositionConfig() is
+intended to used in SMBUS mode.
+
+
+
stm32f10x_tim.h/.c files:
+
+
Change the TIM_DMABurstLength_xBytes definitions to TIM_DMABurstLength_xTansfers
+
+
+
+
+
+
+
3.4.0
+- 10/15/2010
+
+
+
General
+
+
+
+
Add support for STM32F10x High-density value line devices.
+
+
+
+
STM32F10x_StdPeriph_Driver
+
+
+
+
+
+
stm32f10x_bkp.h/.c
+
+
Delete BKP registers definition from stm32f10x_bkp.c and use defines within stm32f10x.h file.
+
+
stm32f10x_can.h/.c
+
+
Delete CAN registers definition from stm32f10x_can.c and use defines within stm32f10x.h file.
+
+
Update the wording of some defines and Asserts macro.
+
+
CAN_GetFlagStatus()
+and CAN_ClearFlag() functions: updated to support new flags (were not
+supported in previous version). These flags are: CAN_FLAG_RQCP0,
+CAN_FLAG_RQCP1, CAN_FLAG_RQCP2, CAN_FLAG_FMP1, CAN_FLAG_FF1,
+CAN_FLAG_FOV1, CAN_FLAG_FMP0, CAN_FLAG_FF0, CAN_FLAG_FOV0,
+CAN_FLAG_WKU, CAN_FLAG_SLAK and CAN_FLAG_LEC.
+
+
CAN_GetITStatus()
+function: add a check of the interrupt enable bit before getting the
+status of corresponding interrupt pending bit.
+
+
CAN_ClearITPendingBit() function: correct the procedure to clear the interrupt pending bit.
+
+
+
stm32f10x_crc.h/.c
+
+
Delete CRC registers definition from stm32f10x_crc.c and use defines within stm32f10x.h file.
+
+
stm32f10x_dac.h/.c
+
+
Delete DAC registers definition from stm32f10x_dac.c and use defines within stm32f10x.h file.
+
+
stm32f10x_dbgmcu.h/.c
+
+
Delete DBGMCU registers definition from stm32f10x_dbgmcu.c and use defines within stm32f10x.h file.
+
+
stm32f10x_dma.h/.c
+
+
Delete DMA registers definition from stm32f10x_dma.c and use defines within stm32f10x.h file.
+
Add new function "void DMA_SetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx, uint16_t DataNumber);"
+
+
+
stm32f10x_flash.h/.c
+
+
FLASH functions (Erase and Program) updated to always clear the "PG", "MER" and "PER" bits even in case of TimeOut Error.
+
+
stm32f10x_fsmc.h/.c
+
+
Add new member "FSMC_AsynchronousWait" in "FSMC_NORSRAMInitTypeDef" structure.
+
+
stm32f10x_gpio.h/.c
+
+
GPIO_PinRemapConfig() function: add new values for GPIO_Remap parameter, to support new remap for TIM6, TIM7 and DAC DMA requests, TIM12 and DAC Triggers / DMA2_Channel5 Interrupt mapping.
+
+
stm32f10x_pwr.h/.c
+
+
Delete PWR registers definition from stm32f10x_pwr.c and use defines within stm32f10x.h and core_cm3.h files.
+
+
stm32f10x_rtc.h/.c
+
+
Delete RTC registers definition from stm32f10x_rtc.c and use defines within stm32f10x.h file.
+
+
stm32f10x_spi.h/.c
+
+
Add new definition for I2S Audio Clock frequencies "I2S_AudioFreq_192k".
+
+
stm32f10x_tim.h/.c
+
Add new definition for TIM Input Capture Polarity "TIM_ICPolarity_BothEdge".
+
+
+
+
3.3.0
+- 04/16/2010
+
+
General
+
Add support for STM32F10x XL-density devices.
I2C driver: events description and management enhancement.
+
STM32F10x_StdPeriph_Driver
+
stm32f10x_dbgmcu.h/.c
DBGMCU_Config() function: add new values DBGMCU_TIMx_STOP (x: 9..14) for DBGMCU_Periph parameter.
stm32f10x_flash.h/.c:
+updated to support Bank2 of XL-density devices (up to 1MByte of Flash
+memory). For more details, refer to the description provided within
+stm32f10x_flash.c file.
stm32f10x_gpio.h/.c
GPIO_PinRemapConfig() function: add new values for GPIO_Remap parameter, to support new remap for FSMC_NADV pin and TIM9..11,13,14.
stm32f10x_i2c.h/.c: I2C events description and management enhancement.
I2C_CheckEvent()
+function: updated to check whether the last event contains the
+I2C_EVENT (instead of check whether the last event is equal to
+I2C_EVENT)
Add
+detailed description of I2C events and how to manage them using the
+functions provided by this driver. For more information, refer to
+stm32f10x_i2c.h and stm32f10x_i2c.c files.
stm32f10x_rcc.h/.c: updated to support TIM9..TIM14 APB clock and reset configuration
stm32f10x_tim.h/.c: updated to support new Timers TIM9..TIM14.
Add support
+for STM32 Low-density Value line (STM32F100x4/6) and
+Medium-density Value line (STM32F100x8/B) devices.
+
Almost
+peripherals drivers were updated to support Value
+line devices features
+
Drivers limitations fix and enhancements.
+
+
+
+
STM32F10x_StdPeriph_Driver
+
+
+
Add new
+firmware driver for CEC peripheral: stm32f10x_cec.h and stm32f10x_cec.c
+
Timers drivers stm32f10x_tim.h/.c: add support for new General Purpose Timers: TIM15, TIM16 and TIM17.
+
RCC driver: add support for new Value peripherals: HDMI-CEC, TIM15, TIM16 and TIM17.
+
GPIO driver: add new remap parameters for TIM1, TIM15, TIM16, TIM17 and HDMI-CEC: GPIO_Remap_TIM1_DMA, GPIO_Remap_TIM15, GPIO_Remap_TIM16, GPIO_Remap_TIM17, GPIO_Remap_CEC.
+
USART
+driver: add support for Oversampling by 8 mode and onebit method. 2
+functions has been added: USART_OverSampling8Cmd() and
+USART_OneBitMethodCmd().
+
+
DAC
+driver: add new functions handling the DAC under run feature:
+DAC_ITConfig(), DAC_GetFlagStatus(), DAC_ClearFlag(), DAC_GetITStatus()
+and DAC_ClearITPendingBit().
+
DBGMCU driver: add new parameters for TIM15, TIM16 and TIM17: DBGMCU_TIM15_STOP, DBGMCU_TIM16_STOP, DBGMCU_TIM17_STOP.
+
+
FLASH
+driver: the FLASH_EraseOptionBytes() function updated. This is now just
+erasing the option bytes without modifying the RDP status either
+enabled or disabled.
+
PWR
+driver: the PWR_EnterSTOPMode() function updated. When woken up from
+STOP mode, this function resets again the SLEEPDEEP bit in the
+Cortex-M3 System Control register to allow Sleep mode entering.
+
+
+
+
License
+
Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); You may not use this package except in compliance with the License. You may obtain a copy of the License at:
Unless
+required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See
+the License for the specific language governing permissions and
+limitations under the License.
+
+
+
For
+complete documentation on STM32(CORTEX M3) 32-Bit Microcontrollers
+visit www.st.com/STM32
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Libraries/STM32F10x_StdPeriph_Driver/inc/misc.h b/Libraries/STM32F10x_StdPeriph_Driver/inc/misc.h
new file mode 100644
index 0000000..0fea5b2
--- /dev/null
+++ b/Libraries/STM32F10x_StdPeriph_Driver/inc/misc.h
@@ -0,0 +1,226 @@
+/**
+ ******************************************************************************
+ * @file misc.h
+ * @author MCD Application Team
+ * @version V3.6.1
+ * @date 05-March-2012
+ * @brief This file contains all the functions prototypes for the miscellaneous
+ * firmware library functions (add-on to CMSIS functions).
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F10x_FSMC_H
+#define __STM32F10x_FSMC_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f10x.h"
+
+/** @addtogroup STM32F10x_StdPeriph_Driver
+ * @{
+ */
+
+/** @addtogroup FSMC
+ * @{
+ */
+
+/** @defgroup FSMC_Exported_Types
+ * @{
+ */
+
+/**
+ * @brief Timing parameters For NOR/SRAM Banks
+ */
+
+typedef struct
+{
+ uint32_t FSMC_AddressSetupTime; /*!< Defines the number of HCLK cycles to configure
+ the duration of the address setup time.
+ This parameter can be a value between 0 and 0xF.
+ @note: It is not used with synchronous NOR Flash memories. */
+
+ uint32_t FSMC_AddressHoldTime; /*!< Defines the number of HCLK cycles to configure
+ the duration of the address hold time.
+ This parameter can be a value between 0 and 0xF.
+ @note: It is not used with synchronous NOR Flash memories.*/
+
+ uint32_t FSMC_DataSetupTime; /*!< Defines the number of HCLK cycles to configure
+ the duration of the data setup time.
+ This parameter can be a value between 0 and 0xFF.
+ @note: It is used for SRAMs, ROMs and asynchronous multiplexed NOR Flash memories. */
+
+ uint32_t FSMC_BusTurnAroundDuration; /*!< Defines the number of HCLK cycles to configure
+ the duration of the bus turnaround.
+ This parameter can be a value between 0 and 0xF.
+ @note: It is only used for multiplexed NOR Flash memories. */
+
+ uint32_t FSMC_CLKDivision; /*!< Defines the period of CLK clock output signal, expressed in number of HCLK cycles.
+ This parameter can be a value between 1 and 0xF.
+ @note: This parameter is not used for asynchronous NOR Flash, SRAM or ROM accesses. */
+
+ uint32_t FSMC_DataLatency; /*!< Defines the number of memory clock cycles to issue
+ to the memory before getting the first data.
+ The value of this parameter depends on the memory type as shown below:
+ - It must be set to 0 in case of a CRAM
+ - It is don't care in asynchronous NOR, SRAM or ROM accesses
+ - It may assume a value between 0 and 0xF in NOR Flash memories
+ with synchronous burst mode enable */
+
+ uint32_t FSMC_AccessMode; /*!< Specifies the asynchronous access mode.
+ This parameter can be a value of @ref FSMC_Access_Mode */
+}FSMC_NORSRAMTimingInitTypeDef;
+
+/**
+ * @brief FSMC NOR/SRAM Init structure definition
+ */
+
+typedef struct
+{
+ uint32_t FSMC_Bank; /*!< Specifies the NOR/SRAM memory bank that will be used.
+ This parameter can be a value of @ref FSMC_NORSRAM_Bank */
+
+ uint32_t FSMC_DataAddressMux; /*!< Specifies whether the address and data values are
+ multiplexed on the databus or not.
+ This parameter can be a value of @ref FSMC_Data_Address_Bus_Multiplexing */
+
+ uint32_t FSMC_MemoryType; /*!< Specifies the type of external memory attached to
+ the corresponding memory bank.
+ This parameter can be a value of @ref FSMC_Memory_Type */
+
+ uint32_t FSMC_MemoryDataWidth; /*!< Specifies the external memory device width.
+ This parameter can be a value of @ref FSMC_Data_Width */
+
+ uint32_t FSMC_BurstAccessMode; /*!< Enables or disables the burst access mode for Flash memory,
+ valid only with synchronous burst Flash memories.
+ This parameter can be a value of @ref FSMC_Burst_Access_Mode */
+
+ uint32_t FSMC_AsynchronousWait; /*!< Enables or disables wait signal during asynchronous transfers,
+ valid only with asynchronous Flash memories.
+ This parameter can be a value of @ref FSMC_AsynchronousWait */
+
+ uint32_t FSMC_WaitSignalPolarity; /*!< Specifies the wait signal polarity, valid only when accessing
+ the Flash memory in burst mode.
+ This parameter can be a value of @ref FSMC_Wait_Signal_Polarity */
+
+ uint32_t FSMC_WrapMode; /*!< Enables or disables the Wrapped burst access mode for Flash
+ memory, valid only when accessing Flash memories in burst mode.
+ This parameter can be a value of @ref FSMC_Wrap_Mode */
+
+ uint32_t FSMC_WaitSignalActive; /*!< Specifies if the wait signal is asserted by the memory one
+ clock cycle before the wait state or during the wait state,
+ valid only when accessing memories in burst mode.
+ This parameter can be a value of @ref FSMC_Wait_Timing */
+
+ uint32_t FSMC_WriteOperation; /*!< Enables or disables the write operation in the selected bank by the FSMC.
+ This parameter can be a value of @ref FSMC_Write_Operation */
+
+ uint32_t FSMC_WaitSignal; /*!< Enables or disables the wait-state insertion via wait
+ signal, valid for Flash memory access in burst mode.
+ This parameter can be a value of @ref FSMC_Wait_Signal */
+
+ uint32_t FSMC_ExtendedMode; /*!< Enables or disables the extended mode.
+ This parameter can be a value of @ref FSMC_Extended_Mode */
+
+ uint32_t FSMC_WriteBurst; /*!< Enables or disables the write burst operation.
+ This parameter can be a value of @ref FSMC_Write_Burst */
+
+ FSMC_NORSRAMTimingInitTypeDef* FSMC_ReadWriteTimingStruct; /*!< Timing Parameters for write and read access if the ExtendedMode is not used*/
+
+ FSMC_NORSRAMTimingInitTypeDef* FSMC_WriteTimingStruct; /*!< Timing Parameters for write access if the ExtendedMode is used*/
+}FSMC_NORSRAMInitTypeDef;
+
+/**
+ * @brief Timing parameters For FSMC NAND and PCCARD Banks
+ */
+
+typedef struct
+{
+ uint32_t FSMC_SetupTime; /*!< Defines the number of HCLK cycles to setup address before
+ the command assertion for NAND-Flash read or write access
+ to common/Attribute or I/O memory space (depending on
+ the memory space timing to be configured).
+ This parameter can be a value between 0 and 0xFF.*/
+
+ uint32_t FSMC_WaitSetupTime; /*!< Defines the minimum number of HCLK cycles to assert the
+ command for NAND-Flash read or write access to
+ common/Attribute or I/O memory space (depending on the
+ memory space timing to be configured).
+ This parameter can be a number between 0x00 and 0xFF */
+
+ uint32_t FSMC_HoldSetupTime; /*!< Defines the number of HCLK clock cycles to hold address
+ (and data for write access) after the command deassertion
+ for NAND-Flash read or write access to common/Attribute
+ or I/O memory space (depending on the memory space timing
+ to be configured).
+ This parameter can be a number between 0x00 and 0xFF */
+
+ uint32_t FSMC_HiZSetupTime; /*!< Defines the number of HCLK clock cycles during which the
+ databus is kept in HiZ after the start of a NAND-Flash
+ write access to common/Attribute or I/O memory space (depending
+ on the memory space timing to be configured).
+ This parameter can be a number between 0x00 and 0xFF */
+}FSMC_NAND_PCCARDTimingInitTypeDef;
+
+/**
+ * @brief FSMC NAND Init structure definition
+ */
+
+typedef struct
+{
+ uint32_t FSMC_Bank; /*!< Specifies the NAND memory bank that will be used.
+ This parameter can be a value of @ref FSMC_NAND_Bank */
+
+ uint32_t FSMC_Waitfeature; /*!< Enables or disables the Wait feature for the NAND Memory Bank.
+ This parameter can be any value of @ref FSMC_Wait_feature */
+
+ uint32_t FSMC_MemoryDataWidth; /*!< Specifies the external memory device width.
+ This parameter can be any value of @ref FSMC_Data_Width */
+
+ uint32_t FSMC_ECC; /*!< Enables or disables the ECC computation.
+ This parameter can be any value of @ref FSMC_ECC */
+
+ uint32_t FSMC_ECCPageSize; /*!< Defines the page size for the extended ECC.
+ This parameter can be any value of @ref FSMC_ECC_Page_Size */
+
+ uint32_t FSMC_TCLRSetupTime; /*!< Defines the number of HCLK cycles to configure the
+ delay between CLE low and RE low.
+ This parameter can be a value between 0 and 0xFF. */
+
+ uint32_t FSMC_TARSetupTime; /*!< Defines the number of HCLK cycles to configure the
+ delay between ALE low and RE low.
+ This parameter can be a number between 0x0 and 0xFF */
+
+ FSMC_NAND_PCCARDTimingInitTypeDef* FSMC_CommonSpaceTimingStruct; /*!< FSMC Common Space Timing */
+
+ FSMC_NAND_PCCARDTimingInitTypeDef* FSMC_AttributeSpaceTimingStruct; /*!< FSMC Attribute Space Timing */
+}FSMC_NANDInitTypeDef;
+
+/**
+ * @brief FSMC PCCARD Init structure definition
+ */
+
+typedef struct
+{
+ uint32_t FSMC_Waitfeature; /*!< Enables or disables the Wait feature for the Memory Bank.
+ This parameter can be any value of @ref FSMC_Wait_feature */
+
+ uint32_t FSMC_TCLRSetupTime; /*!< Defines the number of HCLK cycles to configure the
+ delay between CLE low and RE low.
+ This parameter can be a value between 0 and 0xFF. */
+
+ uint32_t FSMC_TARSetupTime; /*!< Defines the number of HCLK cycles to configure the
+ delay between ALE low and RE low.
+ This parameter can be a number between 0x0 and 0xFF */
+
+
+ FSMC_NAND_PCCARDTimingInitTypeDef* FSMC_CommonSpaceTimingStruct; /*!< FSMC Common Space Timing */
+
+ FSMC_NAND_PCCARDTimingInitTypeDef* FSMC_AttributeSpaceTimingStruct; /*!< FSMC Attribute Space Timing */
+
+ FSMC_NAND_PCCARDTimingInitTypeDef* FSMC_IOSpaceTimingStruct; /*!< FSMC IO Space Timing */
+}FSMC_PCCARDInitTypeDef;
+
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Exported_Constants
+ * @{
+ */
+
+/** @defgroup FSMC_NORSRAM_Bank
+ * @{
+ */
+#define FSMC_Bank1_NORSRAM1 ((uint32_t)0x00000000)
+#define FSMC_Bank1_NORSRAM2 ((uint32_t)0x00000002)
+#define FSMC_Bank1_NORSRAM3 ((uint32_t)0x00000004)
+#define FSMC_Bank1_NORSRAM4 ((uint32_t)0x00000006)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_NAND_Bank
+ * @{
+ */
+#define FSMC_Bank2_NAND ((uint32_t)0x00000010)
+#define FSMC_Bank3_NAND ((uint32_t)0x00000100)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_PCCARD_Bank
+ * @{
+ */
+#define FSMC_Bank4_PCCARD ((uint32_t)0x00001000)
+/**
+ * @}
+ */
+
+#define IS_FSMC_NORSRAM_BANK(BANK) (((BANK) == FSMC_Bank1_NORSRAM1) || \
+ ((BANK) == FSMC_Bank1_NORSRAM2) || \
+ ((BANK) == FSMC_Bank1_NORSRAM3) || \
+ ((BANK) == FSMC_Bank1_NORSRAM4))
+
+#define IS_FSMC_NAND_BANK(BANK) (((BANK) == FSMC_Bank2_NAND) || \
+ ((BANK) == FSMC_Bank3_NAND))
+
+#define IS_FSMC_GETFLAG_BANK(BANK) (((BANK) == FSMC_Bank2_NAND) || \
+ ((BANK) == FSMC_Bank3_NAND) || \
+ ((BANK) == FSMC_Bank4_PCCARD))
+
+#define IS_FSMC_IT_BANK(BANK) (((BANK) == FSMC_Bank2_NAND) || \
+ ((BANK) == FSMC_Bank3_NAND) || \
+ ((BANK) == FSMC_Bank4_PCCARD))
+
+/** @defgroup NOR_SRAM_Controller
+ * @{
+ */
+
+/** @defgroup FSMC_Data_Address_Bus_Multiplexing
+ * @{
+ */
+
+#define FSMC_DataAddressMux_Disable ((uint32_t)0x00000000)
+#define FSMC_DataAddressMux_Enable ((uint32_t)0x00000002)
+#define IS_FSMC_MUX(MUX) (((MUX) == FSMC_DataAddressMux_Disable) || \
+ ((MUX) == FSMC_DataAddressMux_Enable))
+
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Memory_Type
+ * @{
+ */
+
+#define FSMC_MemoryType_SRAM ((uint32_t)0x00000000)
+#define FSMC_MemoryType_PSRAM ((uint32_t)0x00000004)
+#define FSMC_MemoryType_NOR ((uint32_t)0x00000008)
+#define IS_FSMC_MEMORY(MEMORY) (((MEMORY) == FSMC_MemoryType_SRAM) || \
+ ((MEMORY) == FSMC_MemoryType_PSRAM)|| \
+ ((MEMORY) == FSMC_MemoryType_NOR))
+
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Data_Width
+ * @{
+ */
+
+#define FSMC_MemoryDataWidth_8b ((uint32_t)0x00000000)
+#define FSMC_MemoryDataWidth_16b ((uint32_t)0x00000010)
+#define IS_FSMC_MEMORY_WIDTH(WIDTH) (((WIDTH) == FSMC_MemoryDataWidth_8b) || \
+ ((WIDTH) == FSMC_MemoryDataWidth_16b))
+
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Burst_Access_Mode
+ * @{
+ */
+
+#define FSMC_BurstAccessMode_Disable ((uint32_t)0x00000000)
+#define FSMC_BurstAccessMode_Enable ((uint32_t)0x00000100)
+#define IS_FSMC_BURSTMODE(STATE) (((STATE) == FSMC_BurstAccessMode_Disable) || \
+ ((STATE) == FSMC_BurstAccessMode_Enable))
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_AsynchronousWait
+ * @{
+ */
+#define FSMC_AsynchronousWait_Disable ((uint32_t)0x00000000)
+#define FSMC_AsynchronousWait_Enable ((uint32_t)0x00008000)
+#define IS_FSMC_ASYNWAIT(STATE) (((STATE) == FSMC_AsynchronousWait_Disable) || \
+ ((STATE) == FSMC_AsynchronousWait_Enable))
+
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Wait_Signal_Polarity
+ * @{
+ */
+
+#define FSMC_WaitSignalPolarity_Low ((uint32_t)0x00000000)
+#define FSMC_WaitSignalPolarity_High ((uint32_t)0x00000200)
+#define IS_FSMC_WAIT_POLARITY(POLARITY) (((POLARITY) == FSMC_WaitSignalPolarity_Low) || \
+ ((POLARITY) == FSMC_WaitSignalPolarity_High))
+
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Wrap_Mode
+ * @{
+ */
+
+#define FSMC_WrapMode_Disable ((uint32_t)0x00000000)
+#define FSMC_WrapMode_Enable ((uint32_t)0x00000400)
+#define IS_FSMC_WRAP_MODE(MODE) (((MODE) == FSMC_WrapMode_Disable) || \
+ ((MODE) == FSMC_WrapMode_Enable))
+
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Wait_Timing
+ * @{
+ */
+
+#define FSMC_WaitSignalActive_BeforeWaitState ((uint32_t)0x00000000)
+#define FSMC_WaitSignalActive_DuringWaitState ((uint32_t)0x00000800)
+#define IS_FSMC_WAIT_SIGNAL_ACTIVE(ACTIVE) (((ACTIVE) == FSMC_WaitSignalActive_BeforeWaitState) || \
+ ((ACTIVE) == FSMC_WaitSignalActive_DuringWaitState))
+
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Write_Operation
+ * @{
+ */
+
+#define FSMC_WriteOperation_Disable ((uint32_t)0x00000000)
+#define FSMC_WriteOperation_Enable ((uint32_t)0x00001000)
+#define IS_FSMC_WRITE_OPERATION(OPERATION) (((OPERATION) == FSMC_WriteOperation_Disable) || \
+ ((OPERATION) == FSMC_WriteOperation_Enable))
+
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Wait_Signal
+ * @{
+ */
+
+#define FSMC_WaitSignal_Disable ((uint32_t)0x00000000)
+#define FSMC_WaitSignal_Enable ((uint32_t)0x00002000)
+#define IS_FSMC_WAITE_SIGNAL(SIGNAL) (((SIGNAL) == FSMC_WaitSignal_Disable) || \
+ ((SIGNAL) == FSMC_WaitSignal_Enable))
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Extended_Mode
+ * @{
+ */
+
+#define FSMC_ExtendedMode_Disable ((uint32_t)0x00000000)
+#define FSMC_ExtendedMode_Enable ((uint32_t)0x00004000)
+
+#define IS_FSMC_EXTENDED_MODE(MODE) (((MODE) == FSMC_ExtendedMode_Disable) || \
+ ((MODE) == FSMC_ExtendedMode_Enable))
+
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Write_Burst
+ * @{
+ */
+
+#define FSMC_WriteBurst_Disable ((uint32_t)0x00000000)
+#define FSMC_WriteBurst_Enable ((uint32_t)0x00080000)
+#define IS_FSMC_WRITE_BURST(BURST) (((BURST) == FSMC_WriteBurst_Disable) || \
+ ((BURST) == FSMC_WriteBurst_Enable))
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Address_Setup_Time
+ * @{
+ */
+
+#define IS_FSMC_ADDRESS_SETUP_TIME(TIME) ((TIME) <= 0xF)
+
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Address_Hold_Time
+ * @{
+ */
+
+#define IS_FSMC_ADDRESS_HOLD_TIME(TIME) ((TIME) <= 0xF)
+
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Data_Setup_Time
+ * @{
+ */
+
+#define IS_FSMC_DATASETUP_TIME(TIME) (((TIME) > 0) && ((TIME) <= 0xFF))
+
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Bus_Turn_around_Duration
+ * @{
+ */
+
+#define IS_FSMC_TURNAROUND_TIME(TIME) ((TIME) <= 0xF)
+
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_CLK_Division
+ * @{
+ */
+
+#define IS_FSMC_CLK_DIV(DIV) ((DIV) <= 0xF)
+
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Data_Latency
+ * @{
+ */
+
+#define IS_FSMC_DATA_LATENCY(LATENCY) ((LATENCY) <= 0xF)
+
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Access_Mode
+ * @{
+ */
+
+#define FSMC_AccessMode_A ((uint32_t)0x00000000)
+#define FSMC_AccessMode_B ((uint32_t)0x10000000)
+#define FSMC_AccessMode_C ((uint32_t)0x20000000)
+#define FSMC_AccessMode_D ((uint32_t)0x30000000)
+#define IS_FSMC_ACCESS_MODE(MODE) (((MODE) == FSMC_AccessMode_A) || \
+ ((MODE) == FSMC_AccessMode_B) || \
+ ((MODE) == FSMC_AccessMode_C) || \
+ ((MODE) == FSMC_AccessMode_D))
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup NAND_PCCARD_Controller
+ * @{
+ */
+
+/** @defgroup FSMC_Wait_feature
+ * @{
+ */
+
+#define FSMC_Waitfeature_Disable ((uint32_t)0x00000000)
+#define FSMC_Waitfeature_Enable ((uint32_t)0x00000002)
+#define IS_FSMC_WAIT_FEATURE(FEATURE) (((FEATURE) == FSMC_Waitfeature_Disable) || \
+ ((FEATURE) == FSMC_Waitfeature_Enable))
+
+/**
+ * @}
+ */
+
+
+/** @defgroup FSMC_ECC
+ * @{
+ */
+
+#define FSMC_ECC_Disable ((uint32_t)0x00000000)
+#define FSMC_ECC_Enable ((uint32_t)0x00000040)
+#define IS_FSMC_ECC_STATE(STATE) (((STATE) == FSMC_ECC_Disable) || \
+ ((STATE) == FSMC_ECC_Enable))
+
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_ECC_Page_Size
+ * @{
+ */
+
+#define FSMC_ECCPageSize_256Bytes ((uint32_t)0x00000000)
+#define FSMC_ECCPageSize_512Bytes ((uint32_t)0x00020000)
+#define FSMC_ECCPageSize_1024Bytes ((uint32_t)0x00040000)
+#define FSMC_ECCPageSize_2048Bytes ((uint32_t)0x00060000)
+#define FSMC_ECCPageSize_4096Bytes ((uint32_t)0x00080000)
+#define FSMC_ECCPageSize_8192Bytes ((uint32_t)0x000A0000)
+#define IS_FSMC_ECCPAGE_SIZE(SIZE) (((SIZE) == FSMC_ECCPageSize_256Bytes) || \
+ ((SIZE) == FSMC_ECCPageSize_512Bytes) || \
+ ((SIZE) == FSMC_ECCPageSize_1024Bytes) || \
+ ((SIZE) == FSMC_ECCPageSize_2048Bytes) || \
+ ((SIZE) == FSMC_ECCPageSize_4096Bytes) || \
+ ((SIZE) == FSMC_ECCPageSize_8192Bytes))
+
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_TCLR_Setup_Time
+ * @{
+ */
+
+#define IS_FSMC_TCLR_TIME(TIME) ((TIME) <= 0xFF)
+
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_TAR_Setup_Time
+ * @{
+ */
+
+#define IS_FSMC_TAR_TIME(TIME) ((TIME) <= 0xFF)
+
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Setup_Time
+ * @{
+ */
+
+#define IS_FSMC_SETUP_TIME(TIME) ((TIME) <= 0xFF)
+
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Wait_Setup_Time
+ * @{
+ */
+
+#define IS_FSMC_WAIT_TIME(TIME) ((TIME) <= 0xFF)
+
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Hold_Setup_Time
+ * @{
+ */
+
+#define IS_FSMC_HOLD_TIME(TIME) ((TIME) <= 0xFF)
+
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_HiZ_Setup_Time
+ * @{
+ */
+
+#define IS_FSMC_HIZ_TIME(TIME) ((TIME) <= 0xFF)
+
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Interrupt_sources
+ * @{
+ */
+
+#define FSMC_IT_RisingEdge ((uint32_t)0x00000008)
+#define FSMC_IT_Level ((uint32_t)0x00000010)
+#define FSMC_IT_FallingEdge ((uint32_t)0x00000020)
+#define IS_FSMC_IT(IT) ((((IT) & (uint32_t)0xFFFFFFC7) == 0x00000000) && ((IT) != 0x00000000))
+#define IS_FSMC_GET_IT(IT) (((IT) == FSMC_IT_RisingEdge) || \
+ ((IT) == FSMC_IT_Level) || \
+ ((IT) == FSMC_IT_FallingEdge))
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Flags
+ * @{
+ */
+
+#define FSMC_FLAG_RisingEdge ((uint32_t)0x00000001)
+#define FSMC_FLAG_Level ((uint32_t)0x00000002)
+#define FSMC_FLAG_FallingEdge ((uint32_t)0x00000004)
+#define FSMC_FLAG_FEMPT ((uint32_t)0x00000040)
+#define IS_FSMC_GET_FLAG(FLAG) (((FLAG) == FSMC_FLAG_RisingEdge) || \
+ ((FLAG) == FSMC_FLAG_Level) || \
+ ((FLAG) == FSMC_FLAG_FallingEdge) || \
+ ((FLAG) == FSMC_FLAG_FEMPT))
+
+#define IS_FSMC_CLEAR_FLAG(FLAG) ((((FLAG) & (uint32_t)0xFFFFFFF8) == 0x00000000) && ((FLAG) != 0x00000000))
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Exported_Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Exported_Functions
+ * @{
+ */
+
+void FSMC_NORSRAMDeInit(uint32_t FSMC_Bank);
+void FSMC_NANDDeInit(uint32_t FSMC_Bank);
+void FSMC_PCCARDDeInit(void);
+void FSMC_NORSRAMInit(FSMC_NORSRAMInitTypeDef* FSMC_NORSRAMInitStruct);
+void FSMC_NANDInit(FSMC_NANDInitTypeDef* FSMC_NANDInitStruct);
+void FSMC_PCCARDInit(FSMC_PCCARDInitTypeDef* FSMC_PCCARDInitStruct);
+void FSMC_NORSRAMStructInit(FSMC_NORSRAMInitTypeDef* FSMC_NORSRAMInitStruct);
+void FSMC_NANDStructInit(FSMC_NANDInitTypeDef* FSMC_NANDInitStruct);
+void FSMC_PCCARDStructInit(FSMC_PCCARDInitTypeDef* FSMC_PCCARDInitStruct);
+void FSMC_NORSRAMCmd(uint32_t FSMC_Bank, FunctionalState NewState);
+void FSMC_NANDCmd(uint32_t FSMC_Bank, FunctionalState NewState);
+void FSMC_PCCARDCmd(FunctionalState NewState);
+void FSMC_NANDECCCmd(uint32_t FSMC_Bank, FunctionalState NewState);
+uint32_t FSMC_GetECC(uint32_t FSMC_Bank);
+void FSMC_ITConfig(uint32_t FSMC_Bank, uint32_t FSMC_IT, FunctionalState NewState);
+FlagStatus FSMC_GetFlagStatus(uint32_t FSMC_Bank, uint32_t FSMC_FLAG);
+void FSMC_ClearFlag(uint32_t FSMC_Bank, uint32_t FSMC_FLAG);
+ITStatus FSMC_GetITStatus(uint32_t FSMC_Bank, uint32_t FSMC_IT);
+void FSMC_ClearITPendingBit(uint32_t FSMC_Bank, uint32_t FSMC_IT);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__STM32F10x_FSMC_H */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_gpio.h b/Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_gpio.h
new file mode 100644
index 0000000..f67cc0e
--- /dev/null
+++ b/Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_gpio.h
@@ -0,0 +1,391 @@
+/**
+ ******************************************************************************
+ * @file stm32f10x_gpio.h
+ * @author MCD Application Team
+ * @version V3.6.1
+ * @date 05-March-2012
+ * @brief This file contains all the functions prototypes for the GPIO
+ * firmware library.
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F10x_I2C_H
+#define __STM32F10x_I2C_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f10x.h"
+
+/** @addtogroup STM32F10x_StdPeriph_Driver
+ * @{
+ */
+
+/** @addtogroup I2C
+ * @{
+ */
+
+/** @defgroup I2C_Exported_Types
+ * @{
+ */
+
+/**
+ * @brief I2C Init structure definition
+ */
+
+typedef struct
+{
+ uint32_t I2C_ClockSpeed; /*!< Specifies the clock frequency.
+ This parameter must be set to a value lower than 400kHz */
+
+ uint16_t I2C_Mode; /*!< Specifies the I2C mode.
+ This parameter can be a value of @ref I2C_mode */
+
+ uint16_t I2C_DutyCycle; /*!< Specifies the I2C fast mode duty cycle.
+ This parameter can be a value of @ref I2C_duty_cycle_in_fast_mode */
+
+ uint16_t I2C_OwnAddress1; /*!< Specifies the first device own address.
+ This parameter can be a 7-bit or 10-bit address. */
+
+ uint16_t I2C_Ack; /*!< Enables or disables the acknowledgement.
+ This parameter can be a value of @ref I2C_acknowledgement */
+
+ uint16_t I2C_AcknowledgedAddress; /*!< Specifies if 7-bit or 10-bit address is acknowledged.
+ This parameter can be a value of @ref I2C_acknowledged_address */
+}I2C_InitTypeDef;
+
+/**
+ * @}
+ */
+
+
+/** @defgroup I2C_Exported_Constants
+ * @{
+ */
+
+#define IS_I2C_ALL_PERIPH(PERIPH) (((PERIPH) == I2C1) || \
+ ((PERIPH) == I2C2))
+/** @defgroup I2C_mode
+ * @{
+ */
+
+#define I2C_Mode_I2C ((uint16_t)0x0000)
+#define I2C_Mode_SMBusDevice ((uint16_t)0x0002)
+#define I2C_Mode_SMBusHost ((uint16_t)0x000A)
+#define IS_I2C_MODE(MODE) (((MODE) == I2C_Mode_I2C) || \
+ ((MODE) == I2C_Mode_SMBusDevice) || \
+ ((MODE) == I2C_Mode_SMBusHost))
+/**
+ * @}
+ */
+
+/** @defgroup I2C_duty_cycle_in_fast_mode
+ * @{
+ */
+
+#define I2C_DutyCycle_16_9 ((uint16_t)0x4000) /*!< I2C fast mode Tlow/Thigh = 16/9 */
+#define I2C_DutyCycle_2 ((uint16_t)0xBFFF) /*!< I2C fast mode Tlow/Thigh = 2 */
+#define IS_I2C_DUTY_CYCLE(CYCLE) (((CYCLE) == I2C_DutyCycle_16_9) || \
+ ((CYCLE) == I2C_DutyCycle_2))
+/**
+ * @}
+ */
+
+/** @defgroup I2C_acknowledgement
+ * @{
+ */
+
+#define I2C_Ack_Enable ((uint16_t)0x0400)
+#define I2C_Ack_Disable ((uint16_t)0x0000)
+#define IS_I2C_ACK_STATE(STATE) (((STATE) == I2C_Ack_Enable) || \
+ ((STATE) == I2C_Ack_Disable))
+/**
+ * @}
+ */
+
+/** @defgroup I2C_transfer_direction
+ * @{
+ */
+
+#define I2C_Direction_Transmitter ((uint8_t)0x00)
+#define I2C_Direction_Receiver ((uint8_t)0x01)
+#define IS_I2C_DIRECTION(DIRECTION) (((DIRECTION) == I2C_Direction_Transmitter) || \
+ ((DIRECTION) == I2C_Direction_Receiver))
+/**
+ * @}
+ */
+
+/** @defgroup I2C_acknowledged_address
+ * @{
+ */
+
+#define I2C_AcknowledgedAddress_7bit ((uint16_t)0x4000)
+#define I2C_AcknowledgedAddress_10bit ((uint16_t)0xC000)
+#define IS_I2C_ACKNOWLEDGE_ADDRESS(ADDRESS) (((ADDRESS) == I2C_AcknowledgedAddress_7bit) || \
+ ((ADDRESS) == I2C_AcknowledgedAddress_10bit))
+/**
+ * @}
+ */
+
+/** @defgroup I2C_registers
+ * @{
+ */
+
+#define I2C_Register_CR1 ((uint8_t)0x00)
+#define I2C_Register_CR2 ((uint8_t)0x04)
+#define I2C_Register_OAR1 ((uint8_t)0x08)
+#define I2C_Register_OAR2 ((uint8_t)0x0C)
+#define I2C_Register_DR ((uint8_t)0x10)
+#define I2C_Register_SR1 ((uint8_t)0x14)
+#define I2C_Register_SR2 ((uint8_t)0x18)
+#define I2C_Register_CCR ((uint8_t)0x1C)
+#define I2C_Register_TRISE ((uint8_t)0x20)
+#define IS_I2C_REGISTER(REGISTER) (((REGISTER) == I2C_Register_CR1) || \
+ ((REGISTER) == I2C_Register_CR2) || \
+ ((REGISTER) == I2C_Register_OAR1) || \
+ ((REGISTER) == I2C_Register_OAR2) || \
+ ((REGISTER) == I2C_Register_DR) || \
+ ((REGISTER) == I2C_Register_SR1) || \
+ ((REGISTER) == I2C_Register_SR2) || \
+ ((REGISTER) == I2C_Register_CCR) || \
+ ((REGISTER) == I2C_Register_TRISE))
+/**
+ * @}
+ */
+
+/** @defgroup I2C_SMBus_alert_pin_level
+ * @{
+ */
+
+#define I2C_SMBusAlert_Low ((uint16_t)0x2000)
+#define I2C_SMBusAlert_High ((uint16_t)0xDFFF)
+#define IS_I2C_SMBUS_ALERT(ALERT) (((ALERT) == I2C_SMBusAlert_Low) || \
+ ((ALERT) == I2C_SMBusAlert_High))
+/**
+ * @}
+ */
+
+/** @defgroup I2C_PEC_position
+ * @{
+ */
+
+#define I2C_PECPosition_Next ((uint16_t)0x0800)
+#define I2C_PECPosition_Current ((uint16_t)0xF7FF)
+#define IS_I2C_PEC_POSITION(POSITION) (((POSITION) == I2C_PECPosition_Next) || \
+ ((POSITION) == I2C_PECPosition_Current))
+/**
+ * @}
+ */
+
+/** @defgroup I2C_NCAK_position
+ * @{
+ */
+
+#define I2C_NACKPosition_Next ((uint16_t)0x0800)
+#define I2C_NACKPosition_Current ((uint16_t)0xF7FF)
+#define IS_I2C_NACK_POSITION(POSITION) (((POSITION) == I2C_NACKPosition_Next) || \
+ ((POSITION) == I2C_NACKPosition_Current))
+/**
+ * @}
+ */
+
+/** @defgroup I2C_interrupts_definition
+ * @{
+ */
+
+#define I2C_IT_BUF ((uint16_t)0x0400)
+#define I2C_IT_EVT ((uint16_t)0x0200)
+#define I2C_IT_ERR ((uint16_t)0x0100)
+#define IS_I2C_CONFIG_IT(IT) ((((IT) & (uint16_t)0xF8FF) == 0x00) && ((IT) != 0x00))
+/**
+ * @}
+ */
+
+/** @defgroup I2C_interrupts_definition
+ * @{
+ */
+
+#define I2C_IT_SMBALERT ((uint32_t)0x01008000)
+#define I2C_IT_TIMEOUT ((uint32_t)0x01004000)
+#define I2C_IT_PECERR ((uint32_t)0x01001000)
+#define I2C_IT_OVR ((uint32_t)0x01000800)
+#define I2C_IT_AF ((uint32_t)0x01000400)
+#define I2C_IT_ARLO ((uint32_t)0x01000200)
+#define I2C_IT_BERR ((uint32_t)0x01000100)
+#define I2C_IT_TXE ((uint32_t)0x06000080)
+#define I2C_IT_RXNE ((uint32_t)0x06000040)
+#define I2C_IT_STOPF ((uint32_t)0x02000010)
+#define I2C_IT_ADD10 ((uint32_t)0x02000008)
+#define I2C_IT_BTF ((uint32_t)0x02000004)
+#define I2C_IT_ADDR ((uint32_t)0x02000002)
+#define I2C_IT_SB ((uint32_t)0x02000001)
+
+#define IS_I2C_CLEAR_IT(IT) ((((IT) & (uint16_t)0x20FF) == 0x00) && ((IT) != (uint16_t)0x00))
+
+#define IS_I2C_GET_IT(IT) (((IT) == I2C_IT_SMBALERT) || ((IT) == I2C_IT_TIMEOUT) || \
+ ((IT) == I2C_IT_PECERR) || ((IT) == I2C_IT_OVR) || \
+ ((IT) == I2C_IT_AF) || ((IT) == I2C_IT_ARLO) || \
+ ((IT) == I2C_IT_BERR) || ((IT) == I2C_IT_TXE) || \
+ ((IT) == I2C_IT_RXNE) || ((IT) == I2C_IT_STOPF) || \
+ ((IT) == I2C_IT_ADD10) || ((IT) == I2C_IT_BTF) || \
+ ((IT) == I2C_IT_ADDR) || ((IT) == I2C_IT_SB))
+/**
+ * @}
+ */
+
+/** @defgroup I2C_flags_definition
+ * @{
+ */
+
+/**
+ * @brief SR2 register flags
+ */
+
+#define I2C_FLAG_DUALF ((uint32_t)0x00800000)
+#define I2C_FLAG_SMBHOST ((uint32_t)0x00400000)
+#define I2C_FLAG_SMBDEFAULT ((uint32_t)0x00200000)
+#define I2C_FLAG_GENCALL ((uint32_t)0x00100000)
+#define I2C_FLAG_TRA ((uint32_t)0x00040000)
+#define I2C_FLAG_BUSY ((uint32_t)0x00020000)
+#define I2C_FLAG_MSL ((uint32_t)0x00010000)
+
+/**
+ * @brief SR1 register flags
+ */
+
+#define I2C_FLAG_SMBALERT ((uint32_t)0x10008000)
+#define I2C_FLAG_TIMEOUT ((uint32_t)0x10004000)
+#define I2C_FLAG_PECERR ((uint32_t)0x10001000)
+#define I2C_FLAG_OVR ((uint32_t)0x10000800)
+#define I2C_FLAG_AF ((uint32_t)0x10000400)
+#define I2C_FLAG_ARLO ((uint32_t)0x10000200)
+#define I2C_FLAG_BERR ((uint32_t)0x10000100)
+#define I2C_FLAG_TXE ((uint32_t)0x10000080)
+#define I2C_FLAG_RXNE ((uint32_t)0x10000040)
+#define I2C_FLAG_STOPF ((uint32_t)0x10000010)
+#define I2C_FLAG_ADD10 ((uint32_t)0x10000008)
+#define I2C_FLAG_BTF ((uint32_t)0x10000004)
+#define I2C_FLAG_ADDR ((uint32_t)0x10000002)
+#define I2C_FLAG_SB ((uint32_t)0x10000001)
+
+#define IS_I2C_CLEAR_FLAG(FLAG) ((((FLAG) & (uint16_t)0x20FF) == 0x00) && ((FLAG) != (uint16_t)0x00))
+
+#define IS_I2C_GET_FLAG(FLAG) (((FLAG) == I2C_FLAG_DUALF) || ((FLAG) == I2C_FLAG_SMBHOST) || \
+ ((FLAG) == I2C_FLAG_SMBDEFAULT) || ((FLAG) == I2C_FLAG_GENCALL) || \
+ ((FLAG) == I2C_FLAG_TRA) || ((FLAG) == I2C_FLAG_BUSY) || \
+ ((FLAG) == I2C_FLAG_MSL) || ((FLAG) == I2C_FLAG_SMBALERT) || \
+ ((FLAG) == I2C_FLAG_TIMEOUT) || ((FLAG) == I2C_FLAG_PECERR) || \
+ ((FLAG) == I2C_FLAG_OVR) || ((FLAG) == I2C_FLAG_AF) || \
+ ((FLAG) == I2C_FLAG_ARLO) || ((FLAG) == I2C_FLAG_BERR) || \
+ ((FLAG) == I2C_FLAG_TXE) || ((FLAG) == I2C_FLAG_RXNE) || \
+ ((FLAG) == I2C_FLAG_STOPF) || ((FLAG) == I2C_FLAG_ADD10) || \
+ ((FLAG) == I2C_FLAG_BTF) || ((FLAG) == I2C_FLAG_ADDR) || \
+ ((FLAG) == I2C_FLAG_SB))
+/**
+ * @}
+ */
+
+/** @defgroup I2C_Events
+ * @{
+ */
+
+/*========================================
+
+ I2C Master Events (Events grouped in order of communication)
+ ==========================================*/
+/**
+ * @brief Communication start
+ *
+ * After sending the START condition (I2C_GenerateSTART() function) the master
+ * has to wait for this event. It means that the Start condition has been correctly
+ * released on the I2C bus (the bus is free, no other devices is communicating).
+ *
+ */
+/* --EV5 */
+#define I2C_EVENT_MASTER_MODE_SELECT ((uint32_t)0x00030001) /* BUSY, MSL and SB flag */
+
+/**
+ * @brief Address Acknowledge
+ *
+ * After checking on EV5 (start condition correctly released on the bus), the
+ * master sends the address of the slave(s) with which it will communicate
+ * (I2C_Send7bitAddress() function, it also determines the direction of the communication:
+ * Master transmitter or Receiver). Then the master has to wait that a slave acknowledges
+ * his address. If an acknowledge is sent on the bus, one of the following events will
+ * be set:
+ *
+ * 1) In case of Master Receiver (7-bit addressing): the I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED
+ * event is set.
+ *
+ * 2) In case of Master Transmitter (7-bit addressing): the I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED
+ * is set
+ *
+ * 3) In case of 10-Bit addressing mode, the master (just after generating the START
+ * and checking on EV5) has to send the header of 10-bit addressing mode (I2C_SendData()
+ * function). Then master should wait on EV9. It means that the 10-bit addressing
+ * header has been correctly sent on the bus. Then master should send the second part of
+ * the 10-bit address (LSB) using the function I2C_Send7bitAddress(). Then master
+ * should wait for event EV6.
+ *
+ */
+
+/* --EV6 */
+#define I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED ((uint32_t)0x00070082) /* BUSY, MSL, ADDR, TXE and TRA flags */
+#define I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED ((uint32_t)0x00030002) /* BUSY, MSL and ADDR flags */
+/* --EV9 */
+#define I2C_EVENT_MASTER_MODE_ADDRESS10 ((uint32_t)0x00030008) /* BUSY, MSL and ADD10 flags */
+
+/**
+ * @brief Communication events
+ *
+ * If a communication is established (START condition generated and slave address
+ * acknowledged) then the master has to check on one of the following events for
+ * communication procedures:
+ *
+ * 1) Master Receiver mode: The master has to wait on the event EV7 then to read
+ * the data received from the slave (I2C_ReceiveData() function).
+ *
+ * 2) Master Transmitter mode: The master has to send data (I2C_SendData()
+ * function) then to wait on event EV8 or EV8_2.
+ * These two events are similar:
+ * - EV8 means that the data has been written in the data register and is
+ * being shifted out.
+ * - EV8_2 means that the data has been physically shifted out and output
+ * on the bus.
+ * In most cases, using EV8 is sufficient for the application.
+ * Using EV8_2 leads to a slower communication but ensure more reliable test.
+ * EV8_2 is also more suitable than EV8 for testing on the last data transmission
+ * (before Stop condition generation).
+ *
+ * @note In case the user software does not guarantee that this event EV7 is
+ * managed before the current byte end of transfer, then user may check on EV7
+ * and BTF flag at the same time (ie. (I2C_EVENT_MASTER_BYTE_RECEIVED | I2C_FLAG_BTF)).
+ * In this case the communication may be slower.
+ *
+ */
+
+/* Master RECEIVER mode -----------------------------*/
+/* --EV7 */
+#define I2C_EVENT_MASTER_BYTE_RECEIVED ((uint32_t)0x00030040) /* BUSY, MSL and RXNE flags */
+
+/* Master TRANSMITTER mode --------------------------*/
+/* --EV8 */
+#define I2C_EVENT_MASTER_BYTE_TRANSMITTING ((uint32_t)0x00070080) /* TRA, BUSY, MSL, TXE flags */
+/* --EV8_2 */
+#define I2C_EVENT_MASTER_BYTE_TRANSMITTED ((uint32_t)0x00070084) /* TRA, BUSY, MSL, TXE and BTF flags */
+
+
+/*========================================
+
+ I2C Slave Events (Events grouped in order of communication)
+ ==========================================*/
+
+/**
+ * @brief Communication start events
+ *
+ * Wait on one of these events at the start of the communication. It means that
+ * the I2C peripheral detected a Start condition on the bus (generated by master
+ * device) followed by the peripheral address. The peripheral generates an ACK
+ * condition on the bus (if the acknowledge feature is enabled through function
+ * I2C_AcknowledgeConfig()) and the events listed above are set :
+ *
+ * 1) In normal case (only one address managed by the slave), when the address
+ * sent by the master matches the own address of the peripheral (configured by
+ * I2C_OwnAddress1 field) the I2C_EVENT_SLAVE_XXX_ADDRESS_MATCHED event is set
+ * (where XXX could be TRANSMITTER or RECEIVER).
+ *
+ * 2) In case the address sent by the master matches the second address of the
+ * peripheral (configured by the function I2C_OwnAddress2Config() and enabled
+ * by the function I2C_DualAddressCmd()) the events I2C_EVENT_SLAVE_XXX_SECONDADDRESS_MATCHED
+ * (where XXX could be TRANSMITTER or RECEIVER) are set.
+ *
+ * 3) In case the address sent by the master is General Call (address 0x00) and
+ * if the General Call is enabled for the peripheral (using function I2C_GeneralCallCmd())
+ * the following event is set I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED.
+ *
+ */
+
+/* --EV1 (all the events below are variants of EV1) */
+/* 1) Case of One Single Address managed by the slave */
+#define I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED ((uint32_t)0x00020002) /* BUSY and ADDR flags */
+#define I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED ((uint32_t)0x00060082) /* TRA, BUSY, TXE and ADDR flags */
+
+/* 2) Case of Dual address managed by the slave */
+#define I2C_EVENT_SLAVE_RECEIVER_SECONDADDRESS_MATCHED ((uint32_t)0x00820000) /* DUALF and BUSY flags */
+#define I2C_EVENT_SLAVE_TRANSMITTER_SECONDADDRESS_MATCHED ((uint32_t)0x00860080) /* DUALF, TRA, BUSY and TXE flags */
+
+/* 3) Case of General Call enabled for the slave */
+#define I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED ((uint32_t)0x00120000) /* GENCALL and BUSY flags */
+
+/**
+ * @brief Communication events
+ *
+ * Wait on one of these events when EV1 has already been checked and:
+ *
+ * - Slave RECEIVER mode:
+ * - EV2: When the application is expecting a data byte to be received.
+ * - EV4: When the application is expecting the end of the communication: master
+ * sends a stop condition and data transmission is stopped.
+ *
+ * - Slave Transmitter mode:
+ * - EV3: When a byte has been transmitted by the slave and the application is expecting
+ * the end of the byte transmission. The two events I2C_EVENT_SLAVE_BYTE_TRANSMITTED and
+ * I2C_EVENT_SLAVE_BYTE_TRANSMITTING are similar. The second one can optionally be
+ * used when the user software doesn't guarantee the EV3 is managed before the
+ * current byte end of transfer.
+ * - EV3_2: When the master sends a NACK in order to tell slave that data transmission
+ * shall end (before sending the STOP condition). In this case slave has to stop sending
+ * data bytes and expect a Stop condition on the bus.
+ *
+ * @note In case the user software does not guarantee that the event EV2 is
+ * managed before the current byte end of transfer, then user may check on EV2
+ * and BTF flag at the same time (ie. (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_BTF)).
+ * In this case the communication may be slower.
+ *
+ */
+
+/* Slave RECEIVER mode --------------------------*/
+/* --EV2 */
+#define I2C_EVENT_SLAVE_BYTE_RECEIVED ((uint32_t)0x00020040) /* BUSY and RXNE flags */
+/* --EV4 */
+#define I2C_EVENT_SLAVE_STOP_DETECTED ((uint32_t)0x00000010) /* STOPF flag */
+
+/* Slave TRANSMITTER mode -----------------------*/
+/* --EV3 */
+#define I2C_EVENT_SLAVE_BYTE_TRANSMITTED ((uint32_t)0x00060084) /* TRA, BUSY, TXE and BTF flags */
+#define I2C_EVENT_SLAVE_BYTE_TRANSMITTING ((uint32_t)0x00060080) /* TRA, BUSY and TXE flags */
+/* --EV3_2 */
+#define I2C_EVENT_SLAVE_ACK_FAILURE ((uint32_t)0x00000400) /* AF flag */
+
+/*=========================== End of Events Description ==========================================*/
+
+#define IS_I2C_EVENT(EVENT) (((EVENT) == I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED) || \
+ ((EVENT) == I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED) || \
+ ((EVENT) == I2C_EVENT_SLAVE_TRANSMITTER_SECONDADDRESS_MATCHED) || \
+ ((EVENT) == I2C_EVENT_SLAVE_RECEIVER_SECONDADDRESS_MATCHED) || \
+ ((EVENT) == I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED) || \
+ ((EVENT) == I2C_EVENT_SLAVE_BYTE_RECEIVED) || \
+ ((EVENT) == (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_DUALF)) || \
+ ((EVENT) == (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_GENCALL)) || \
+ ((EVENT) == I2C_EVENT_SLAVE_BYTE_TRANSMITTED) || \
+ ((EVENT) == (I2C_EVENT_SLAVE_BYTE_TRANSMITTED | I2C_FLAG_DUALF)) || \
+ ((EVENT) == (I2C_EVENT_SLAVE_BYTE_TRANSMITTED | I2C_FLAG_GENCALL)) || \
+ ((EVENT) == I2C_EVENT_SLAVE_STOP_DETECTED) || \
+ ((EVENT) == I2C_EVENT_MASTER_MODE_SELECT) || \
+ ((EVENT) == I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) || \
+ ((EVENT) == I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED) || \
+ ((EVENT) == I2C_EVENT_MASTER_BYTE_RECEIVED) || \
+ ((EVENT) == I2C_EVENT_MASTER_BYTE_TRANSMITTED) || \
+ ((EVENT) == I2C_EVENT_MASTER_BYTE_TRANSMITTING) || \
+ ((EVENT) == I2C_EVENT_MASTER_MODE_ADDRESS10) || \
+ ((EVENT) == I2C_EVENT_SLAVE_ACK_FAILURE))
+/**
+ * @}
+ */
+
+/** @defgroup I2C_own_address1
+ * @{
+ */
+
+#define IS_I2C_OWN_ADDRESS1(ADDRESS1) ((ADDRESS1) <= 0x3FF)
+/**
+ * @}
+ */
+
+/** @defgroup I2C_clock_speed
+ * @{
+ */
+
+#define IS_I2C_CLOCK_SPEED(SPEED) (((SPEED) >= 0x1) && ((SPEED) <= 400000))
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup I2C_Exported_Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup I2C_Exported_Functions
+ * @{
+ */
+
+void I2C_DeInit(I2C_TypeDef* I2Cx);
+void I2C_Init(I2C_TypeDef* I2Cx, I2C_InitTypeDef* I2C_InitStruct);
+void I2C_StructInit(I2C_InitTypeDef* I2C_InitStruct);
+void I2C_Cmd(I2C_TypeDef* I2Cx, FunctionalState NewState);
+void I2C_DMACmd(I2C_TypeDef* I2Cx, FunctionalState NewState);
+void I2C_DMALastTransferCmd(I2C_TypeDef* I2Cx, FunctionalState NewState);
+void I2C_GenerateSTART(I2C_TypeDef* I2Cx, FunctionalState NewState);
+void I2C_GenerateSTOP(I2C_TypeDef* I2Cx, FunctionalState NewState);
+void I2C_AcknowledgeConfig(I2C_TypeDef* I2Cx, FunctionalState NewState);
+void I2C_OwnAddress2Config(I2C_TypeDef* I2Cx, uint8_t Address);
+void I2C_DualAddressCmd(I2C_TypeDef* I2Cx, FunctionalState NewState);
+void I2C_GeneralCallCmd(I2C_TypeDef* I2Cx, FunctionalState NewState);
+void I2C_ITConfig(I2C_TypeDef* I2Cx, uint16_t I2C_IT, FunctionalState NewState);
+void I2C_SendData(I2C_TypeDef* I2Cx, uint8_t Data);
+uint8_t I2C_ReceiveData(I2C_TypeDef* I2Cx);
+void I2C_Send7bitAddress(I2C_TypeDef* I2Cx, uint8_t Address, uint8_t I2C_Direction);
+uint16_t I2C_ReadRegister(I2C_TypeDef* I2Cx, uint8_t I2C_Register);
+void I2C_SoftwareResetCmd(I2C_TypeDef* I2Cx, FunctionalState NewState);
+void I2C_NACKPositionConfig(I2C_TypeDef* I2Cx, uint16_t I2C_NACKPosition);
+void I2C_SMBusAlertConfig(I2C_TypeDef* I2Cx, uint16_t I2C_SMBusAlert);
+void I2C_TransmitPEC(I2C_TypeDef* I2Cx, FunctionalState NewState);
+void I2C_PECPositionConfig(I2C_TypeDef* I2Cx, uint16_t I2C_PECPosition);
+void I2C_CalculatePEC(I2C_TypeDef* I2Cx, FunctionalState NewState);
+uint8_t I2C_GetPEC(I2C_TypeDef* I2Cx);
+void I2C_ARPCmd(I2C_TypeDef* I2Cx, FunctionalState NewState);
+void I2C_StretchClockCmd(I2C_TypeDef* I2Cx, FunctionalState NewState);
+void I2C_FastModeDutyCycleConfig(I2C_TypeDef* I2Cx, uint16_t I2C_DutyCycle);
+
+/**
+ * @brief
+ ****************************************************************************************
+ *
+ * I2C State Monitoring Functions
+ *
+ ****************************************************************************************
+ * This I2C driver provides three different ways for I2C state monitoring
+ * depending on the application requirements and constraints:
+ *
+ *
+ * 1) Basic state monitoring:
+ * Using I2C_CheckEvent() function:
+ * It compares the status registers (SR1 and SR2) content to a given event
+ * (can be the combination of one or more flags).
+ * It returns SUCCESS if the current status includes the given flags
+ * and returns ERROR if one or more flags are missing in the current status.
+ * - When to use:
+ * - This function is suitable for most applications as well as for startup
+ * activity since the events are fully described in the product reference manual
+ * (RM0008).
+ * - It is also suitable for users who need to define their own events.
+ * - Limitations:
+ * - If an error occurs (ie. error flags are set besides to the monitored flags),
+ * the I2C_CheckEvent() function may return SUCCESS despite the communication
+ * hold or corrupted real state.
+ * In this case, it is advised to use error interrupts to monitor the error
+ * events and handle them in the interrupt IRQ handler.
+ *
+ * @note
+ * For error management, it is advised to use the following functions:
+ * - I2C_ITConfig() to configure and enable the error interrupts (I2C_IT_ERR).
+ * - I2Cx_ER_IRQHandler() which is called when the error interrupt occurs.
+ * Where x is the peripheral instance (I2C1, I2C2 ...)
+ * - I2C_GetFlagStatus() or I2C_GetITStatus() to be called into I2Cx_ER_IRQHandler()
+ * in order to determine which error occurred.
+ * - I2C_ClearFlag() or I2C_ClearITPendingBit() and/or I2C_SoftwareResetCmd()
+ * and/or I2C_GenerateStop() in order to clear the error flag and source,
+ * and return to correct communication status.
+ *
+ *
+ * 2) Advanced state monitoring:
+ * Using the function I2C_GetLastEvent() which returns the image of both status
+ * registers in a single word (uint32_t) (Status Register 2 value is shifted left
+ * by 16 bits and concatenated to Status Register 1).
+ * - When to use:
+ * - This function is suitable for the same applications above but it allows to
+ * overcome the limitations of I2C_GetFlagStatus() function (see below).
+ * The returned value could be compared to events already defined in the
+ * library (stm32f10x_i2c.h) or to custom values defined by user.
+ * - This function is suitable when multiple flags are monitored at the same time.
+ * - At the opposite of I2C_CheckEvent() function, this function allows user to
+ * choose when an event is accepted (when all events flags are set and no
+ * other flags are set or just when the needed flags are set like
+ * I2C_CheckEvent() function).
+ * - Limitations:
+ * - User may need to define his own events.
+ * - Same remark concerning the error management is applicable for this
+ * function if user decides to check only regular communication flags (and
+ * ignores error flags).
+ *
+ *
+ * 3) Flag-based state monitoring:
+ * Using the function I2C_GetFlagStatus() which simply returns the status of
+ * one single flag (ie. I2C_FLAG_RXNE ...).
+ * - When to use:
+ * - This function could be used for specific applications or in debug phase.
+ * - It is suitable when only one flag checking is needed (most I2C events
+ * are monitored through multiple flags).
+ * - Limitations:
+ * - When calling this function, the Status register is accessed. Some flags are
+ * cleared when the status register is accessed. So checking the status
+ * of one Flag, may clear other ones.
+ * - Function may need to be called twice or more in order to monitor one
+ * single event.
+ *
+ */
+
+/**
+ *
+ * 1) Basic state monitoring
+ *******************************************************************************
+ */
+ErrorStatus I2C_CheckEvent(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT);
+/**
+ *
+ * 2) Advanced state monitoring
+ *******************************************************************************
+ */
+uint32_t I2C_GetLastEvent(I2C_TypeDef* I2Cx);
+/**
+ *
+ * 3) Flag-based state monitoring
+ *******************************************************************************
+ */
+FlagStatus I2C_GetFlagStatus(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG);
+/**
+ *
+ *******************************************************************************
+ */
+
+void I2C_ClearFlag(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG);
+ITStatus I2C_GetITStatus(I2C_TypeDef* I2Cx, uint32_t I2C_IT);
+void I2C_ClearITPendingBit(I2C_TypeDef* I2Cx, uint32_t I2C_IT);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__STM32F10x_I2C_H */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_iwdg.h b/Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_iwdg.h
new file mode 100644
index 0000000..971ab42
--- /dev/null
+++ b/Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_iwdg.h
@@ -0,0 +1,146 @@
+/**
+ ******************************************************************************
+ * @file stm32f10x_iwdg.h
+ * @author MCD Application Team
+ * @version V3.6.1
+ * @date 05-March-2012
+ * @brief This file contains all the functions prototypes for the IWDG
+ * firmware library.
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f10x_flash.h"
+
+/** @addtogroup STM32F10x_StdPeriph_Driver
+ * @{
+ */
+
+/** @defgroup FLASH
+ * @brief FLASH driver modules
+ * @{
+ */
+
+/** @defgroup FLASH_Private_TypesDefinitions
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup FLASH_Private_Defines
+ * @{
+ */
+
+/* Flash Access Control Register bits */
+#define ACR_LATENCY_Mask ((uint32_t)0x00000038)
+#define ACR_HLFCYA_Mask ((uint32_t)0xFFFFFFF7)
+#define ACR_PRFTBE_Mask ((uint32_t)0xFFFFFFEF)
+
+/* Flash Access Control Register bits */
+#define ACR_PRFTBS_Mask ((uint32_t)0x00000020)
+
+/* Flash Control Register bits */
+#define CR_PG_Set ((uint32_t)0x00000001)
+#define CR_PG_Reset ((uint32_t)0x00001FFE)
+#define CR_PER_Set ((uint32_t)0x00000002)
+#define CR_PER_Reset ((uint32_t)0x00001FFD)
+#define CR_MER_Set ((uint32_t)0x00000004)
+#define CR_MER_Reset ((uint32_t)0x00001FFB)
+#define CR_OPTPG_Set ((uint32_t)0x00000010)
+#define CR_OPTPG_Reset ((uint32_t)0x00001FEF)
+#define CR_OPTER_Set ((uint32_t)0x00000020)
+#define CR_OPTER_Reset ((uint32_t)0x00001FDF)
+#define CR_STRT_Set ((uint32_t)0x00000040)
+#define CR_LOCK_Set ((uint32_t)0x00000080)
+
+/* FLASH Mask */
+#define RDPRT_Mask ((uint32_t)0x00000002)
+#define WRP0_Mask ((uint32_t)0x000000FF)
+#define WRP1_Mask ((uint32_t)0x0000FF00)
+#define WRP2_Mask ((uint32_t)0x00FF0000)
+#define WRP3_Mask ((uint32_t)0xFF000000)
+#define OB_USER_BFB2 ((uint16_t)0x0008)
+
+/* FLASH BANK address */
+#define FLASH_BANK1_END_ADDRESS ((uint32_t)0x807FFFF)
+
+/* Delay definition */
+#define EraseTimeout ((uint32_t)0x000B0000)
+#define ProgramTimeout ((uint32_t)0x00002000)
+/**
+ * @}
+ */
+
+/** @defgroup FLASH_Private_Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup FLASH_Private_Variables
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup FLASH_Private_FunctionPrototypes
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup FLASH_Private_Functions
+ * @{
+ */
+
+/**
+@code
+
+ This driver provides functions to configure and program the Flash memory of all STM32F10x devices,
+ including the latest STM32F10x_XL density devices.
+
+ STM32F10x_XL devices feature up to 1 Mbyte with dual bank architecture for read-while-write (RWW) capability:
+ - bank1: fixed size of 512 Kbytes (256 pages of 2Kbytes each)
+ - bank2: up to 512 Kbytes (up to 256 pages of 2Kbytes each)
+ While other STM32F10x devices features only one bank with memory up to 512 Kbytes.
+
+ In version V3.3.0, some functions were updated and new ones were added to support
+ STM32F10x_XL devices. Thus some functions manages all devices, while other are
+ dedicated for XL devices only.
+
+ The table below presents the list of available functions depending on the used STM32F10x devices.
+
+ ***************************************************
+ * Legacy functions used for all STM32F10x devices *
+ ***************************************************
+ +----------------------------------------------------------------------------------------------------------------------------------+
+ | Functions prototypes |STM32F10x_XL|Other STM32F10x| Comments |
+ | | devices | devices | |
+ |----------------------------------------------------------------------------------------------------------------------------------|
+ |FLASH_SetLatency | Yes | Yes | No change |
+ |----------------------------------------------------------------------------------------------------------------------------------|
+ |FLASH_HalfCycleAccessCmd | Yes | Yes | No change |
+ |----------------------------------------------------------------------------------------------------------------------------------|
+ |FLASH_PrefetchBufferCmd | Yes | Yes | No change |
+ |----------------------------------------------------------------------------------------------------------------------------------|
+ |FLASH_Unlock | Yes | Yes | - For STM32F10X_XL devices: unlock Bank1 and Bank2. |
+ | | | | - For other devices: unlock Bank1 and it is equivalent |
+ | | | | to FLASH_UnlockBank1 function. |
+ |----------------------------------------------------------------------------------------------------------------------------------|
+ |FLASH_Lock | Yes | Yes | - For STM32F10X_XL devices: lock Bank1 and Bank2. |
+ | | | | - For other devices: lock Bank1 and it is equivalent |
+ | | | | to FLASH_LockBank1 function. |
+ |----------------------------------------------------------------------------------------------------------------------------------|
+ |FLASH_ErasePage | Yes | Yes | - For STM32F10x_XL devices: erase a page in Bank1 and Bank2 |
+ | | | | - For other devices: erase a page in Bank1 |
+ |----------------------------------------------------------------------------------------------------------------------------------|
+ |FLASH_EraseAllPages | Yes | Yes | - For STM32F10x_XL devices: erase all pages in Bank1 and Bank2 |
+ | | | | - For other devices: erase all pages in Bank1 |
+ |----------------------------------------------------------------------------------------------------------------------------------|
+ |FLASH_EraseOptionBytes | Yes | Yes | No change |
+ |----------------------------------------------------------------------------------------------------------------------------------|
+ |FLASH_ProgramWord | Yes | Yes | Updated to program up to 1MByte (depending on the used device) |
+ |----------------------------------------------------------------------------------------------------------------------------------|
+ |FLASH_ProgramHalfWord | Yes | Yes | Updated to program up to 1MByte (depending on the used device) |
+ |----------------------------------------------------------------------------------------------------------------------------------|
+ |FLASH_ProgramOptionByteData | Yes | Yes | No change |
+ |----------------------------------------------------------------------------------------------------------------------------------|
+ |FLASH_EnableWriteProtection | Yes | Yes | No change |
+ |----------------------------------------------------------------------------------------------------------------------------------|
+ |FLASH_ReadOutProtection | Yes | Yes | No change |
+ |----------------------------------------------------------------------------------------------------------------------------------|
+ |FLASH_UserOptionByteConfig | Yes | Yes | No change |
+ |----------------------------------------------------------------------------------------------------------------------------------|
+ |FLASH_GetUserOptionByte | Yes | Yes | No change |
+ |----------------------------------------------------------------------------------------------------------------------------------|
+ |FLASH_GetWriteProtectionOptionByte | Yes | Yes | No change |
+ |----------------------------------------------------------------------------------------------------------------------------------|
+ |FLASH_GetReadOutProtectionStatus | Yes | Yes | No change |
+ |----------------------------------------------------------------------------------------------------------------------------------|
+ |FLASH_GetPrefetchBufferStatus | Yes | Yes | No change |
+ |----------------------------------------------------------------------------------------------------------------------------------|
+ |FLASH_ITConfig | Yes | Yes | - For STM32F10x_XL devices: enable Bank1 and Bank2's interrupts|
+ | | | | - For other devices: enable Bank1's interrupts |
+ |----------------------------------------------------------------------------------------------------------------------------------|
+ |FLASH_GetFlagStatus | Yes | Yes | - For STM32F10x_XL devices: return Bank1 and Bank2's flag status|
+ | | | | - For other devices: return Bank1's flag status |
+ |----------------------------------------------------------------------------------------------------------------------------------|
+ |FLASH_ClearFlag | Yes | Yes | - For STM32F10x_XL devices: clear Bank1 and Bank2's flag |
+ | | | | - For other devices: clear Bank1's flag |
+ |----------------------------------------------------------------------------------------------------------------------------------|
+ |FLASH_GetStatus | Yes | Yes | - Return the status of Bank1 (for all devices) |
+ | | | | equivalent to FLASH_GetBank1Status function |
+ |----------------------------------------------------------------------------------------------------------------------------------|
+ |FLASH_WaitForLastOperation | Yes | Yes | - Wait for Bank1 last operation (for all devices) |
+ | | | | equivalent to: FLASH_WaitForLastBank1Operation function |
+ +----------------------------------------------------------------------------------------------------------------------------------+
+
+ ************************************************************************************************************************
+ * New functions used for all STM32F10x devices to manage Bank1: *
+ * - These functions are mainly useful for STM32F10x_XL density devices, to have separate control for Bank1 and bank2 *
+ * - For other devices, these functions are optional (covered by functions listed above) *
+ ************************************************************************************************************************
+ +----------------------------------------------------------------------------------------------------------------------------------+
+ | Functions prototypes |STM32F10x_XL|Other STM32F10x| Comments |
+ | | devices | devices | |
+ |----------------------------------------------------------------------------------------------------------------------------------|
+ | FLASH_UnlockBank1 | Yes | Yes | - Unlock Bank1 |
+ |----------------------------------------------------------------------------------------------------------------------------------|
+ |FLASH_LockBank1 | Yes | Yes | - Lock Bank1 |
+ |----------------------------------------------------------------------------------------------------------------------------------|
+ | FLASH_EraseAllBank1Pages | Yes | Yes | - Erase all pages in Bank1 |
+ |----------------------------------------------------------------------------------------------------------------------------------|
+ | FLASH_GetBank1Status | Yes | Yes | - Return the status of Bank1 |
+ |----------------------------------------------------------------------------------------------------------------------------------|
+ | FLASH_WaitForLastBank1Operation | Yes | Yes | - Wait for Bank1 last operation |
+ +----------------------------------------------------------------------------------------------------------------------------------+
+
+ *****************************************************************************
+ * New Functions used only with STM32F10x_XL density devices to manage Bank2 *
+ *****************************************************************************
+ +----------------------------------------------------------------------------------------------------------------------------------+
+ | Functions prototypes |STM32F10x_XL|Other STM32F10x| Comments |
+ | | devices | devices | |
+ |----------------------------------------------------------------------------------------------------------------------------------|
+ | FLASH_UnlockBank2 | Yes | No | - Unlock Bank2 |
+ |----------------------------------------------------------------------------------------------------------------------------------|
+ |FLASH_LockBank2 | Yes | No | - Lock Bank2 |
+ |----------------------------------------------------------------------------------------------------------------------------------|
+ | FLASH_EraseAllBank2Pages | Yes | No | - Erase all pages in Bank2 |
+ |----------------------------------------------------------------------------------------------------------------------------------|
+ | FLASH_GetBank2Status | Yes | No | - Return the status of Bank2 |
+ |----------------------------------------------------------------------------------------------------------------------------------|
+ | FLASH_WaitForLastBank2Operation | Yes | No | - Wait for Bank2 last operation |
+ |----------------------------------------------------------------------------------------------------------------------------------|
+ | FLASH_BootConfig | Yes | No | - Configure to boot from Bank1 or Bank2 |
+ +----------------------------------------------------------------------------------------------------------------------------------+
+@endcode
+*/
+
+
+/**
+ * @brief Sets the code latency value.
+ * @note This function can be used for all STM32F10x devices.
+ * @param FLASH_Latency: specifies the FLASH Latency value.
+ * This parameter can be one of the following values:
+ * @arg FLASH_Latency_0: FLASH Zero Latency cycle
+ * @arg FLASH_Latency_1: FLASH One Latency cycle
+ * @arg FLASH_Latency_2: FLASH Two Latency cycles
+ * @retval None
+ */
+void FLASH_SetLatency(uint32_t FLASH_Latency)
+{
+ uint32_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_FLASH_LATENCY(FLASH_Latency));
+
+ /* Read the ACR register */
+ tmpreg = FLASH->ACR;
+
+ /* Sets the Latency value */
+ tmpreg &= ACR_LATENCY_Mask;
+ tmpreg |= FLASH_Latency;
+
+ /* Write the ACR register */
+ FLASH->ACR = tmpreg;
+}
+
+/**
+ * @brief Enables or disables the Half cycle flash access.
+ * @note This function can be used for all STM32F10x devices.
+ * @param FLASH_HalfCycleAccess: specifies the FLASH Half cycle Access mode.
+ * This parameter can be one of the following values:
+ * @arg FLASH_HalfCycleAccess_Enable: FLASH Half Cycle Enable
+ * @arg FLASH_HalfCycleAccess_Disable: FLASH Half Cycle Disable
+ * @retval None
+ */
+void FLASH_HalfCycleAccessCmd(uint32_t FLASH_HalfCycleAccess)
+{
+ /* Check the parameters */
+ assert_param(IS_FLASH_HALFCYCLEACCESS_STATE(FLASH_HalfCycleAccess));
+
+ /* Enable or disable the Half cycle access */
+ FLASH->ACR &= ACR_HLFCYA_Mask;
+ FLASH->ACR |= FLASH_HalfCycleAccess;
+}
+
+/**
+ * @brief Enables or disables the Prefetch Buffer.
+ * @note This function can be used for all STM32F10x devices.
+ * @param FLASH_PrefetchBuffer: specifies the Prefetch buffer status.
+ * This parameter can be one of the following values:
+ * @arg FLASH_PrefetchBuffer_Enable: FLASH Prefetch Buffer Enable
+ * @arg FLASH_PrefetchBuffer_Disable: FLASH Prefetch Buffer Disable
+ * @retval None
+ */
+void FLASH_PrefetchBufferCmd(uint32_t FLASH_PrefetchBuffer)
+{
+ /* Check the parameters */
+ assert_param(IS_FLASH_PREFETCHBUFFER_STATE(FLASH_PrefetchBuffer));
+
+ /* Enable or disable the Prefetch Buffer */
+ FLASH->ACR &= ACR_PRFTBE_Mask;
+ FLASH->ACR |= FLASH_PrefetchBuffer;
+}
+
+/**
+ * @brief Unlocks the FLASH Program Erase Controller.
+ * @note This function can be used for all STM32F10x devices.
+ * - For STM32F10X_XL devices this function unlocks Bank1 and Bank2.
+ * - For all other devices it unlocks Bank1 and it is equivalent
+ * to FLASH_UnlockBank1 function..
+ * @param None
+ * @retval None
+ */
+void FLASH_Unlock(void)
+{
+ /* Authorize the FPEC of Bank1 Access */
+ FLASH->KEYR = FLASH_KEY1;
+ FLASH->KEYR = FLASH_KEY2;
+
+#ifdef STM32F10X_XL
+ /* Authorize the FPEC of Bank2 Access */
+ FLASH->KEYR2 = FLASH_KEY1;
+ FLASH->KEYR2 = FLASH_KEY2;
+#endif /* STM32F10X_XL */
+}
+/**
+ * @brief Unlocks the FLASH Bank1 Program Erase Controller.
+ * @note This function can be used for all STM32F10x devices.
+ * - For STM32F10X_XL devices this function unlocks Bank1.
+ * - For all other devices it unlocks Bank1 and it is
+ * equivalent to FLASH_Unlock function.
+ * @param None
+ * @retval None
+ */
+void FLASH_UnlockBank1(void)
+{
+ /* Authorize the FPEC of Bank1 Access */
+ FLASH->KEYR = FLASH_KEY1;
+ FLASH->KEYR = FLASH_KEY2;
+}
+
+#ifdef STM32F10X_XL
+/**
+ * @brief Unlocks the FLASH Bank2 Program Erase Controller.
+ * @note This function can be used only for STM32F10X_XL density devices.
+ * @param None
+ * @retval None
+ */
+void FLASH_UnlockBank2(void)
+{
+ /* Authorize the FPEC of Bank2 Access */
+ FLASH->KEYR2 = FLASH_KEY1;
+ FLASH->KEYR2 = FLASH_KEY2;
+
+}
+#endif /* STM32F10X_XL */
+
+/**
+ * @brief Locks the FLASH Program Erase Controller.
+ * @note This function can be used for all STM32F10x devices.
+ * - For STM32F10X_XL devices this function Locks Bank1 and Bank2.
+ * - For all other devices it Locks Bank1 and it is equivalent
+ * to FLASH_LockBank1 function.
+ * @param None
+ * @retval None
+ */
+void FLASH_Lock(void)
+{
+ /* Set the Lock Bit to lock the FPEC and the CR of Bank1 */
+ FLASH->CR |= CR_LOCK_Set;
+
+#ifdef STM32F10X_XL
+ /* Set the Lock Bit to lock the FPEC and the CR of Bank2 */
+ FLASH->CR2 |= CR_LOCK_Set;
+#endif /* STM32F10X_XL */
+}
+
+/**
+ * @brief Locks the FLASH Bank1 Program Erase Controller.
+ * @note this function can be used for all STM32F10x devices.
+ * - For STM32F10X_XL devices this function Locks Bank1.
+ * - For all other devices it Locks Bank1 and it is equivalent
+ * to FLASH_Lock function.
+ * @param None
+ * @retval None
+ */
+void FLASH_LockBank1(void)
+{
+ /* Set the Lock Bit to lock the FPEC and the CR of Bank1 */
+ FLASH->CR |= CR_LOCK_Set;
+}
+
+#ifdef STM32F10X_XL
+/**
+ * @brief Locks the FLASH Bank2 Program Erase Controller.
+ * @note This function can be used only for STM32F10X_XL density devices.
+ * @param None
+ * @retval None
+ */
+void FLASH_LockBank2(void)
+{
+ /* Set the Lock Bit to lock the FPEC and the CR of Bank2 */
+ FLASH->CR2 |= CR_LOCK_Set;
+}
+#endif /* STM32F10X_XL */
+
+/**
+ * @brief Erases a specified FLASH page.
+ * @note This function can be used for all STM32F10x devices.
+ * @param Page_Address: The page address to be erased.
+ * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
+ * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
+ */
+FLASH_Status FLASH_ErasePage(uint32_t Page_Address)
+{
+ FLASH_Status status = FLASH_COMPLETE;
+ /* Check the parameters */
+ assert_param(IS_FLASH_ADDRESS(Page_Address));
+
+#ifdef STM32F10X_XL
+ if(Page_Address < FLASH_BANK1_END_ADDRESS)
+ {
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastBank1Operation(EraseTimeout);
+ if(status == FLASH_COMPLETE)
+ {
+ /* if the previous operation is completed, proceed to erase the page */
+ FLASH->CR|= CR_PER_Set;
+ FLASH->AR = Page_Address;
+ FLASH->CR|= CR_STRT_Set;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastBank1Operation(EraseTimeout);
+
+ /* Disable the PER Bit */
+ FLASH->CR &= CR_PER_Reset;
+ }
+ }
+ else
+ {
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastBank2Operation(EraseTimeout);
+ if(status == FLASH_COMPLETE)
+ {
+ /* if the previous operation is completed, proceed to erase the page */
+ FLASH->CR2|= CR_PER_Set;
+ FLASH->AR2 = Page_Address;
+ FLASH->CR2|= CR_STRT_Set;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastBank2Operation(EraseTimeout);
+
+ /* Disable the PER Bit */
+ FLASH->CR2 &= CR_PER_Reset;
+ }
+ }
+#else
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(EraseTimeout);
+
+ if(status == FLASH_COMPLETE)
+ {
+ /* if the previous operation is completed, proceed to erase the page */
+ FLASH->CR|= CR_PER_Set;
+ FLASH->AR = Page_Address;
+ FLASH->CR|= CR_STRT_Set;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(EraseTimeout);
+
+ /* Disable the PER Bit */
+ FLASH->CR &= CR_PER_Reset;
+ }
+#endif /* STM32F10X_XL */
+
+ /* Return the Erase Status */
+ return status;
+}
+
+/**
+ * @brief Erases all FLASH pages.
+ * @note This function can be used for all STM32F10x devices.
+ * @param None
+ * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
+ * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
+ */
+FLASH_Status FLASH_EraseAllPages(void)
+{
+ FLASH_Status status = FLASH_COMPLETE;
+
+#ifdef STM32F10X_XL
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastBank1Operation(EraseTimeout);
+
+ if(status == FLASH_COMPLETE)
+ {
+ /* if the previous operation is completed, proceed to erase all pages */
+ FLASH->CR |= CR_MER_Set;
+ FLASH->CR |= CR_STRT_Set;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastBank1Operation(EraseTimeout);
+
+ /* Disable the MER Bit */
+ FLASH->CR &= CR_MER_Reset;
+ }
+ if(status == FLASH_COMPLETE)
+ {
+ /* if the previous operation is completed, proceed to erase all pages */
+ FLASH->CR2 |= CR_MER_Set;
+ FLASH->CR2 |= CR_STRT_Set;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastBank2Operation(EraseTimeout);
+
+ /* Disable the MER Bit */
+ FLASH->CR2 &= CR_MER_Reset;
+ }
+#else
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(EraseTimeout);
+ if(status == FLASH_COMPLETE)
+ {
+ /* if the previous operation is completed, proceed to erase all pages */
+ FLASH->CR |= CR_MER_Set;
+ FLASH->CR |= CR_STRT_Set;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(EraseTimeout);
+
+ /* Disable the MER Bit */
+ FLASH->CR &= CR_MER_Reset;
+ }
+#endif /* STM32F10X_XL */
+
+ /* Return the Erase Status */
+ return status;
+}
+
+/**
+ * @brief Erases all Bank1 FLASH pages.
+ * @note This function can be used for all STM32F10x devices.
+ * - For STM32F10X_XL devices this function erases all Bank1 pages.
+ * - For all other devices it erases all Bank1 pages and it is equivalent
+ * to FLASH_EraseAllPages function.
+ * @param None
+ * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
+ * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
+ */
+FLASH_Status FLASH_EraseAllBank1Pages(void)
+{
+ FLASH_Status status = FLASH_COMPLETE;
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastBank1Operation(EraseTimeout);
+
+ if(status == FLASH_COMPLETE)
+ {
+ /* if the previous operation is completed, proceed to erase all pages */
+ FLASH->CR |= CR_MER_Set;
+ FLASH->CR |= CR_STRT_Set;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastBank1Operation(EraseTimeout);
+
+ /* Disable the MER Bit */
+ FLASH->CR &= CR_MER_Reset;
+ }
+ /* Return the Erase Status */
+ return status;
+}
+
+#ifdef STM32F10X_XL
+/**
+ * @brief Erases all Bank2 FLASH pages.
+ * @note This function can be used only for STM32F10x_XL density devices.
+ * @param None
+ * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
+ * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
+ */
+FLASH_Status FLASH_EraseAllBank2Pages(void)
+{
+ FLASH_Status status = FLASH_COMPLETE;
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastBank2Operation(EraseTimeout);
+
+ if(status == FLASH_COMPLETE)
+ {
+ /* if the previous operation is completed, proceed to erase all pages */
+ FLASH->CR2 |= CR_MER_Set;
+ FLASH->CR2 |= CR_STRT_Set;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastBank2Operation(EraseTimeout);
+
+ /* Disable the MER Bit */
+ FLASH->CR2 &= CR_MER_Reset;
+ }
+ /* Return the Erase Status */
+ return status;
+}
+#endif /* STM32F10X_XL */
+
+/**
+ * @brief Erases the FLASH option bytes.
+ * @note This functions erases all option bytes except the Read protection (RDP).
+ * @note This function can be used for all STM32F10x devices.
+ * @param None
+ * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
+ * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
+ */
+FLASH_Status FLASH_EraseOptionBytes(void)
+{
+ uint16_t rdptmp = RDP_Key;
+
+ FLASH_Status status = FLASH_COMPLETE;
+
+ /* Get the actual read protection Option Byte value */
+ if(FLASH_GetReadOutProtectionStatus() != RESET)
+ {
+ rdptmp = 0x00;
+ }
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(EraseTimeout);
+ if(status == FLASH_COMPLETE)
+ {
+ /* Authorize the small information block programming */
+ FLASH->OPTKEYR = FLASH_KEY1;
+ FLASH->OPTKEYR = FLASH_KEY2;
+
+ /* if the previous operation is completed, proceed to erase the option bytes */
+ FLASH->CR |= CR_OPTER_Set;
+ FLASH->CR |= CR_STRT_Set;
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(EraseTimeout);
+
+ if(status == FLASH_COMPLETE)
+ {
+ /* if the erase operation is completed, disable the OPTER Bit */
+ FLASH->CR &= CR_OPTER_Reset;
+
+ /* Enable the Option Bytes Programming operation */
+ FLASH->CR |= CR_OPTPG_Set;
+ /* Restore the last read protection Option Byte value */
+ OB->RDP = (uint16_t)rdptmp;
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(ProgramTimeout);
+
+ if(status != FLASH_TIMEOUT)
+ {
+ /* if the program operation is completed, disable the OPTPG Bit */
+ FLASH->CR &= CR_OPTPG_Reset;
+ }
+ }
+ else
+ {
+ if (status != FLASH_TIMEOUT)
+ {
+ /* Disable the OPTPG Bit */
+ FLASH->CR &= CR_OPTPG_Reset;
+ }
+ }
+ }
+ /* Return the erase status */
+ return status;
+}
+
+/**
+ * @brief Programs a word at a specified address.
+ * @note This function can be used for all STM32F10x devices.
+ * @param Address: specifies the address to be programmed.
+ * @param Data: specifies the data to be programmed.
+ * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
+ * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
+ */
+FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data)
+{
+ FLASH_Status status = FLASH_COMPLETE;
+ __IO uint32_t tmp = 0;
+
+ /* Check the parameters */
+ assert_param(IS_FLASH_ADDRESS(Address));
+
+#ifdef STM32F10X_XL
+ if(Address < FLASH_BANK1_END_ADDRESS - 2)
+ {
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastBank1Operation(ProgramTimeout);
+ if(status == FLASH_COMPLETE)
+ {
+ /* if the previous operation is completed, proceed to program the new first
+ half word */
+ FLASH->CR |= CR_PG_Set;
+
+ *(__IO uint16_t*)Address = (uint16_t)Data;
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(ProgramTimeout);
+
+ if(status == FLASH_COMPLETE)
+ {
+ /* if the previous operation is completed, proceed to program the new second
+ half word */
+ tmp = Address + 2;
+
+ *(__IO uint16_t*) tmp = Data >> 16;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(ProgramTimeout);
+
+ /* Disable the PG Bit */
+ FLASH->CR &= CR_PG_Reset;
+ }
+ else
+ {
+ /* Disable the PG Bit */
+ FLASH->CR &= CR_PG_Reset;
+ }
+ }
+ }
+ else if(Address == (FLASH_BANK1_END_ADDRESS - 1))
+ {
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastBank1Operation(ProgramTimeout);
+
+ if(status == FLASH_COMPLETE)
+ {
+ /* if the previous operation is completed, proceed to program the new first
+ half word */
+ FLASH->CR |= CR_PG_Set;
+
+ *(__IO uint16_t*)Address = (uint16_t)Data;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastBank1Operation(ProgramTimeout);
+
+ /* Disable the PG Bit */
+ FLASH->CR &= CR_PG_Reset;
+ }
+ else
+ {
+ /* Disable the PG Bit */
+ FLASH->CR &= CR_PG_Reset;
+ }
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastBank2Operation(ProgramTimeout);
+
+ if(status == FLASH_COMPLETE)
+ {
+ /* if the previous operation is completed, proceed to program the new second
+ half word */
+ FLASH->CR2 |= CR_PG_Set;
+ tmp = Address + 2;
+
+ *(__IO uint16_t*) tmp = Data >> 16;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastBank2Operation(ProgramTimeout);
+
+ /* Disable the PG Bit */
+ FLASH->CR2 &= CR_PG_Reset;
+ }
+ else
+ {
+ /* Disable the PG Bit */
+ FLASH->CR2 &= CR_PG_Reset;
+ }
+ }
+ else
+ {
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastBank2Operation(ProgramTimeout);
+
+ if(status == FLASH_COMPLETE)
+ {
+ /* if the previous operation is completed, proceed to program the new first
+ half word */
+ FLASH->CR2 |= CR_PG_Set;
+
+ *(__IO uint16_t*)Address = (uint16_t)Data;
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastBank2Operation(ProgramTimeout);
+
+ if(status == FLASH_COMPLETE)
+ {
+ /* if the previous operation is completed, proceed to program the new second
+ half word */
+ tmp = Address + 2;
+
+ *(__IO uint16_t*) tmp = Data >> 16;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastBank2Operation(ProgramTimeout);
+
+ /* Disable the PG Bit */
+ FLASH->CR2 &= CR_PG_Reset;
+ }
+ else
+ {
+ /* Disable the PG Bit */
+ FLASH->CR2 &= CR_PG_Reset;
+ }
+ }
+ }
+#else
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(ProgramTimeout);
+
+ if(status == FLASH_COMPLETE)
+ {
+ /* if the previous operation is completed, proceed to program the new first
+ half word */
+ FLASH->CR |= CR_PG_Set;
+
+ *(__IO uint16_t*)Address = (uint16_t)Data;
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(ProgramTimeout);
+
+ if(status == FLASH_COMPLETE)
+ {
+ /* if the previous operation is completed, proceed to program the new second
+ half word */
+ tmp = Address + 2;
+
+ *(__IO uint16_t*) tmp = Data >> 16;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(ProgramTimeout);
+
+ /* Disable the PG Bit */
+ FLASH->CR &= CR_PG_Reset;
+ }
+ else
+ {
+ /* Disable the PG Bit */
+ FLASH->CR &= CR_PG_Reset;
+ }
+ }
+#endif /* STM32F10X_XL */
+
+ /* Return the Program Status */
+ return status;
+}
+
+/**
+ * @brief Programs a half word at a specified address.
+ * @note This function can be used for all STM32F10x devices.
+ * @param Address: specifies the address to be programmed.
+ * @param Data: specifies the data to be programmed.
+ * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
+ * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
+ */
+FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data)
+{
+ FLASH_Status status = FLASH_COMPLETE;
+ /* Check the parameters */
+ assert_param(IS_FLASH_ADDRESS(Address));
+
+#ifdef STM32F10X_XL
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(ProgramTimeout);
+
+ if(Address < FLASH_BANK1_END_ADDRESS)
+ {
+ if(status == FLASH_COMPLETE)
+ {
+ /* if the previous operation is completed, proceed to program the new data */
+ FLASH->CR |= CR_PG_Set;
+
+ *(__IO uint16_t*)Address = Data;
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastBank1Operation(ProgramTimeout);
+
+ /* Disable the PG Bit */
+ FLASH->CR &= CR_PG_Reset;
+ }
+ }
+ else
+ {
+ if(status == FLASH_COMPLETE)
+ {
+ /* if the previous operation is completed, proceed to program the new data */
+ FLASH->CR2 |= CR_PG_Set;
+
+ *(__IO uint16_t*)Address = Data;
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastBank2Operation(ProgramTimeout);
+
+ /* Disable the PG Bit */
+ FLASH->CR2 &= CR_PG_Reset;
+ }
+ }
+#else
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(ProgramTimeout);
+
+ if(status == FLASH_COMPLETE)
+ {
+ /* if the previous operation is completed, proceed to program the new data */
+ FLASH->CR |= CR_PG_Set;
+
+ *(__IO uint16_t*)Address = Data;
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(ProgramTimeout);
+
+ /* Disable the PG Bit */
+ FLASH->CR &= CR_PG_Reset;
+ }
+#endif /* STM32F10X_XL */
+
+ /* Return the Program Status */
+ return status;
+}
+
+/**
+ * @brief Programs a half word at a specified Option Byte Data address.
+ * @note This function can be used for all STM32F10x devices.
+ * @param Address: specifies the address to be programmed.
+ * This parameter can be 0x1FFFF804 or 0x1FFFF806.
+ * @param Data: specifies the data to be programmed.
+ * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
+ * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
+ */
+FLASH_Status FLASH_ProgramOptionByteData(uint32_t Address, uint8_t Data)
+{
+ FLASH_Status status = FLASH_COMPLETE;
+ /* Check the parameters */
+ assert_param(IS_OB_DATA_ADDRESS(Address));
+ status = FLASH_WaitForLastOperation(ProgramTimeout);
+
+ if(status == FLASH_COMPLETE)
+ {
+ /* Authorize the small information block programming */
+ FLASH->OPTKEYR = FLASH_KEY1;
+ FLASH->OPTKEYR = FLASH_KEY2;
+ /* Enables the Option Bytes Programming operation */
+ FLASH->CR |= CR_OPTPG_Set;
+ *(__IO uint16_t*)Address = Data;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(ProgramTimeout);
+ if(status != FLASH_TIMEOUT)
+ {
+ /* if the program operation is completed, disable the OPTPG Bit */
+ FLASH->CR &= CR_OPTPG_Reset;
+ }
+ }
+ /* Return the Option Byte Data Program Status */
+ return status;
+}
+
+/**
+ * @brief Write protects the desired pages
+ * @note This function can be used for all STM32F10x devices.
+ * @param FLASH_Pages: specifies the address of the pages to be write protected.
+ * This parameter can be:
+ * @arg For @b STM32_Low-density_devices: value between FLASH_WRProt_Pages0to3 and FLASH_WRProt_Pages28to31
+ * @arg For @b STM32_Medium-density_devices: value between FLASH_WRProt_Pages0to3
+ * and FLASH_WRProt_Pages124to127
+ * @arg For @b STM32_High-density_devices: value between FLASH_WRProt_Pages0to1 and
+ * FLASH_WRProt_Pages60to61 or FLASH_WRProt_Pages62to255
+ * @arg For @b STM32_Connectivity_line_devices: value between FLASH_WRProt_Pages0to1 and
+ * FLASH_WRProt_Pages60to61 or FLASH_WRProt_Pages62to127
+ * @arg For @b STM32_XL-density_devices: value between FLASH_WRProt_Pages0to1 and
+ * FLASH_WRProt_Pages60to61 or FLASH_WRProt_Pages62to511
+ * @arg FLASH_WRProt_AllPages
+ * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
+ * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
+ */
+FLASH_Status FLASH_EnableWriteProtection(uint32_t FLASH_Pages)
+{
+ uint16_t WRP0_Data = 0xFFFF, WRP1_Data = 0xFFFF, WRP2_Data = 0xFFFF, WRP3_Data = 0xFFFF;
+
+ FLASH_Status status = FLASH_COMPLETE;
+
+ /* Check the parameters */
+ assert_param(IS_FLASH_WRPROT_PAGE(FLASH_Pages));
+
+ FLASH_Pages = (uint32_t)(~FLASH_Pages);
+ WRP0_Data = (uint16_t)(FLASH_Pages & WRP0_Mask);
+ WRP1_Data = (uint16_t)((FLASH_Pages & WRP1_Mask) >> 8);
+ WRP2_Data = (uint16_t)((FLASH_Pages & WRP2_Mask) >> 16);
+ WRP3_Data = (uint16_t)((FLASH_Pages & WRP3_Mask) >> 24);
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(ProgramTimeout);
+
+ if(status == FLASH_COMPLETE)
+ {
+ /* Authorizes the small information block programming */
+ FLASH->OPTKEYR = FLASH_KEY1;
+ FLASH->OPTKEYR = FLASH_KEY2;
+ FLASH->CR |= CR_OPTPG_Set;
+ if(WRP0_Data != 0xFF)
+ {
+ OB->WRP0 = WRP0_Data;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(ProgramTimeout);
+ }
+ if((status == FLASH_COMPLETE) && (WRP1_Data != 0xFF))
+ {
+ OB->WRP1 = WRP1_Data;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(ProgramTimeout);
+ }
+ if((status == FLASH_COMPLETE) && (WRP2_Data != 0xFF))
+ {
+ OB->WRP2 = WRP2_Data;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(ProgramTimeout);
+ }
+
+ if((status == FLASH_COMPLETE)&& (WRP3_Data != 0xFF))
+ {
+ OB->WRP3 = WRP3_Data;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(ProgramTimeout);
+ }
+
+ if(status != FLASH_TIMEOUT)
+ {
+ /* if the program operation is completed, disable the OPTPG Bit */
+ FLASH->CR &= CR_OPTPG_Reset;
+ }
+ }
+ /* Return the write protection operation Status */
+ return status;
+}
+
+/**
+ * @brief Enables or disables the read out protection.
+ * @note If the user has already programmed the other option bytes before calling
+ * this function, he must re-program them since this function erases all option bytes.
+ * @note This function can be used for all STM32F10x devices.
+ * @param Newstate: new state of the ReadOut Protection.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
+ * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
+ */
+FLASH_Status FLASH_ReadOutProtection(FunctionalState NewState)
+{
+ FLASH_Status status = FLASH_COMPLETE;
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ status = FLASH_WaitForLastOperation(EraseTimeout);
+ if(status == FLASH_COMPLETE)
+ {
+ /* Authorizes the small information block programming */
+ FLASH->OPTKEYR = FLASH_KEY1;
+ FLASH->OPTKEYR = FLASH_KEY2;
+ FLASH->CR |= CR_OPTER_Set;
+ FLASH->CR |= CR_STRT_Set;
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(EraseTimeout);
+ if(status == FLASH_COMPLETE)
+ {
+ /* if the erase operation is completed, disable the OPTER Bit */
+ FLASH->CR &= CR_OPTER_Reset;
+ /* Enable the Option Bytes Programming operation */
+ FLASH->CR |= CR_OPTPG_Set;
+ if(NewState != DISABLE)
+ {
+ OB->RDP = 0x00;
+ }
+ else
+ {
+ OB->RDP = RDP_Key;
+ }
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(EraseTimeout);
+
+ if(status != FLASH_TIMEOUT)
+ {
+ /* if the program operation is completed, disable the OPTPG Bit */
+ FLASH->CR &= CR_OPTPG_Reset;
+ }
+ }
+ else
+ {
+ if(status != FLASH_TIMEOUT)
+ {
+ /* Disable the OPTER Bit */
+ FLASH->CR &= CR_OPTER_Reset;
+ }
+ }
+ }
+ /* Return the protection operation Status */
+ return status;
+}
+
+/**
+ * @brief Programs the FLASH User Option Byte: IWDG_SW / RST_STOP / RST_STDBY.
+ * @note This function can be used for all STM32F10x devices.
+ * @param OB_IWDG: Selects the IWDG mode
+ * This parameter can be one of the following values:
+ * @arg OB_IWDG_SW: Software IWDG selected
+ * @arg OB_IWDG_HW: Hardware IWDG selected
+ * @param OB_STOP: Reset event when entering STOP mode.
+ * This parameter can be one of the following values:
+ * @arg OB_STOP_NoRST: No reset generated when entering in STOP
+ * @arg OB_STOP_RST: Reset generated when entering in STOP
+ * @param OB_STDBY: Reset event when entering Standby mode.
+ * This parameter can be one of the following values:
+ * @arg OB_STDBY_NoRST: No reset generated when entering in STANDBY
+ * @arg OB_STDBY_RST: Reset generated when entering in STANDBY
+ * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
+ * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
+ */
+FLASH_Status FLASH_UserOptionByteConfig(uint16_t OB_IWDG, uint16_t OB_STOP, uint16_t OB_STDBY)
+{
+ FLASH_Status status = FLASH_COMPLETE;
+
+ /* Check the parameters */
+ assert_param(IS_OB_IWDG_SOURCE(OB_IWDG));
+ assert_param(IS_OB_STOP_SOURCE(OB_STOP));
+ assert_param(IS_OB_STDBY_SOURCE(OB_STDBY));
+
+ /* Authorize the small information block programming */
+ FLASH->OPTKEYR = FLASH_KEY1;
+ FLASH->OPTKEYR = FLASH_KEY2;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(ProgramTimeout);
+
+ if(status == FLASH_COMPLETE)
+ {
+ /* Enable the Option Bytes Programming operation */
+ FLASH->CR |= CR_OPTPG_Set;
+
+ OB->USER = OB_IWDG | (uint16_t)(OB_STOP | (uint16_t)(OB_STDBY | ((uint16_t)0xF8)));
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(ProgramTimeout);
+ if(status != FLASH_TIMEOUT)
+ {
+ /* if the program operation is completed, disable the OPTPG Bit */
+ FLASH->CR &= CR_OPTPG_Reset;
+ }
+ }
+ /* Return the Option Byte program Status */
+ return status;
+}
+
+#ifdef STM32F10X_XL
+/**
+ * @brief Configures to boot from Bank1 or Bank2.
+ * @note This function can be used only for STM32F10x_XL density devices.
+ * @param FLASH_BOOT: select the FLASH Bank to boot from.
+ * This parameter can be one of the following values:
+ * @arg FLASH_BOOT_Bank1: At startup, if boot pins are set in boot from user Flash
+ * position and this parameter is selected the device will boot from Bank1(Default).
+ * @arg FLASH_BOOT_Bank2: At startup, if boot pins are set in boot from user Flash
+ * position and this parameter is selected the device will boot from Bank2 or Bank1,
+ * depending on the activation of the bank. The active banks are checked in
+ * the following order: Bank2, followed by Bank1.
+ * The active bank is recognized by the value programmed at the base address
+ * of the respective bank (corresponding to the initial stack pointer value
+ * in the interrupt vector table).
+ * For more information, please refer to AN2606 from www.st.com.
+ * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
+ * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
+ */
+FLASH_Status FLASH_BootConfig(uint16_t FLASH_BOOT)
+{
+ FLASH_Status status = FLASH_COMPLETE;
+ assert_param(IS_FLASH_BOOT(FLASH_BOOT));
+ /* Authorize the small information block programming */
+ FLASH->OPTKEYR = FLASH_KEY1;
+ FLASH->OPTKEYR = FLASH_KEY2;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(ProgramTimeout);
+
+ if(status == FLASH_COMPLETE)
+ {
+ /* Enable the Option Bytes Programming operation */
+ FLASH->CR |= CR_OPTPG_Set;
+
+ if(FLASH_BOOT == FLASH_BOOT_Bank1)
+ {
+ OB->USER |= OB_USER_BFB2;
+ }
+ else
+ {
+ OB->USER &= (uint16_t)(~(uint16_t)(OB_USER_BFB2));
+ }
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(ProgramTimeout);
+ if(status != FLASH_TIMEOUT)
+ {
+ /* if the program operation is completed, disable the OPTPG Bit */
+ FLASH->CR &= CR_OPTPG_Reset;
+ }
+ }
+ /* Return the Option Byte program Status */
+ return status;
+}
+#endif /* STM32F10X_XL */
+
+/**
+ * @brief Returns the FLASH User Option Bytes values.
+ * @note This function can be used for all STM32F10x devices.
+ * @param None
+ * @retval The FLASH User Option Bytes values:IWDG_SW(Bit0), RST_STOP(Bit1)
+ * and RST_STDBY(Bit2).
+ */
+uint32_t FLASH_GetUserOptionByte(void)
+{
+ /* Return the User Option Byte */
+ return (uint32_t)(FLASH->OBR >> 2);
+}
+
+/**
+ * @brief Returns the FLASH Write Protection Option Bytes Register value.
+ * @note This function can be used for all STM32F10x devices.
+ * @param None
+ * @retval The FLASH Write Protection Option Bytes Register value
+ */
+uint32_t FLASH_GetWriteProtectionOptionByte(void)
+{
+ /* Return the Flash write protection Register value */
+ return (uint32_t)(FLASH->WRPR);
+}
+
+/**
+ * @brief Checks whether the FLASH Read Out Protection Status is set or not.
+ * @note This function can be used for all STM32F10x devices.
+ * @param None
+ * @retval FLASH ReadOut Protection Status(SET or RESET)
+ */
+FlagStatus FLASH_GetReadOutProtectionStatus(void)
+{
+ FlagStatus readoutstatus = RESET;
+ if ((FLASH->OBR & RDPRT_Mask) != (uint32_t)RESET)
+ {
+ readoutstatus = SET;
+ }
+ else
+ {
+ readoutstatus = RESET;
+ }
+ return readoutstatus;
+}
+
+/**
+ * @brief Checks whether the FLASH Prefetch Buffer status is set or not.
+ * @note This function can be used for all STM32F10x devices.
+ * @param None
+ * @retval FLASH Prefetch Buffer Status (SET or RESET).
+ */
+FlagStatus FLASH_GetPrefetchBufferStatus(void)
+{
+ FlagStatus bitstatus = RESET;
+
+ if ((FLASH->ACR & ACR_PRFTBS_Mask) != (uint32_t)RESET)
+ {
+ bitstatus = SET;
+ }
+ else
+ {
+ bitstatus = RESET;
+ }
+ /* Return the new state of FLASH Prefetch Buffer Status (SET or RESET) */
+ return bitstatus;
+}
+
+/**
+ * @brief Enables or disables the specified FLASH interrupts.
+ * @note This function can be used for all STM32F10x devices.
+ * - For STM32F10X_XL devices, enables or disables the specified FLASH interrupts
+ for Bank1 and Bank2.
+ * - For other devices it enables or disables the specified FLASH interrupts for Bank1.
+ * @param FLASH_IT: specifies the FLASH interrupt sources to be enabled or disabled.
+ * This parameter can be any combination of the following values:
+ * @arg FLASH_IT_ERROR: FLASH Error Interrupt
+ * @arg FLASH_IT_EOP: FLASH end of operation Interrupt
+ * @param NewState: new state of the specified Flash interrupts.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void FLASH_ITConfig(uint32_t FLASH_IT, FunctionalState NewState)
+{
+#ifdef STM32F10X_XL
+ /* Check the parameters */
+ assert_param(IS_FLASH_IT(FLASH_IT));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if((FLASH_IT & 0x80000000) != 0x0)
+ {
+ if(NewState != DISABLE)
+ {
+ /* Enable the interrupt sources */
+ FLASH->CR2 |= (FLASH_IT & 0x7FFFFFFF);
+ }
+ else
+ {
+ /* Disable the interrupt sources */
+ FLASH->CR2 &= ~(uint32_t)(FLASH_IT & 0x7FFFFFFF);
+ }
+ }
+ else
+ {
+ if(NewState != DISABLE)
+ {
+ /* Enable the interrupt sources */
+ FLASH->CR |= FLASH_IT;
+ }
+ else
+ {
+ /* Disable the interrupt sources */
+ FLASH->CR &= ~(uint32_t)FLASH_IT;
+ }
+ }
+#else
+ /* Check the parameters */
+ assert_param(IS_FLASH_IT(FLASH_IT));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if(NewState != DISABLE)
+ {
+ /* Enable the interrupt sources */
+ FLASH->CR |= FLASH_IT;
+ }
+ else
+ {
+ /* Disable the interrupt sources */
+ FLASH->CR &= ~(uint32_t)FLASH_IT;
+ }
+#endif /* STM32F10X_XL */
+}
+
+/**
+ * @brief Checks whether the specified FLASH flag is set or not.
+ * @note This function can be used for all STM32F10x devices.
+ * - For STM32F10X_XL devices, this function checks whether the specified
+ * Bank1 or Bank2 flag is set or not.
+ * - For other devices, it checks whether the specified Bank1 flag is
+ * set or not.
+ * @param FLASH_FLAG: specifies the FLASH flag to check.
+ * This parameter can be one of the following values:
+ * @arg FLASH_FLAG_BSY: FLASH Busy flag
+ * @arg FLASH_FLAG_PGERR: FLASH Program error flag
+ * @arg FLASH_FLAG_WRPRTERR: FLASH Write protected error flag
+ * @arg FLASH_FLAG_EOP: FLASH End of Operation flag
+ * @arg FLASH_FLAG_OPTERR: FLASH Option Byte error flag
+ * @retval The new state of FLASH_FLAG (SET or RESET).
+ */
+FlagStatus FLASH_GetFlagStatus(uint32_t FLASH_FLAG)
+{
+ FlagStatus bitstatus = RESET;
+
+#ifdef STM32F10X_XL
+ /* Check the parameters */
+ assert_param(IS_FLASH_GET_FLAG(FLASH_FLAG)) ;
+ if(FLASH_FLAG == FLASH_FLAG_OPTERR)
+ {
+ if((FLASH->OBR & FLASH_FLAG_OPTERR) != (uint32_t)RESET)
+ {
+ bitstatus = SET;
+ }
+ else
+ {
+ bitstatus = RESET;
+ }
+ }
+ else
+ {
+ if((FLASH_FLAG & 0x80000000) != 0x0)
+ {
+ if((FLASH->SR2 & FLASH_FLAG) != (uint32_t)RESET)
+ {
+ bitstatus = SET;
+ }
+ else
+ {
+ bitstatus = RESET;
+ }
+ }
+ else
+ {
+ if((FLASH->SR & FLASH_FLAG) != (uint32_t)RESET)
+ {
+ bitstatus = SET;
+ }
+ else
+ {
+ bitstatus = RESET;
+ }
+ }
+ }
+#else
+ /* Check the parameters */
+ assert_param(IS_FLASH_GET_FLAG(FLASH_FLAG)) ;
+ if(FLASH_FLAG == FLASH_FLAG_OPTERR)
+ {
+ if((FLASH->OBR & FLASH_FLAG_OPTERR) != (uint32_t)RESET)
+ {
+ bitstatus = SET;
+ }
+ else
+ {
+ bitstatus = RESET;
+ }
+ }
+ else
+ {
+ if((FLASH->SR & FLASH_FLAG) != (uint32_t)RESET)
+ {
+ bitstatus = SET;
+ }
+ else
+ {
+ bitstatus = RESET;
+ }
+ }
+#endif /* STM32F10X_XL */
+
+ /* Return the new state of FLASH_FLAG (SET or RESET) */
+ return bitstatus;
+}
+
+/**
+ * @brief Clears the FLASH's pending flags.
+ * @note This function can be used for all STM32F10x devices.
+ * - For STM32F10X_XL devices, this function clears Bank1 or Bank2�s pending flags
+ * - For other devices, it clears Bank1�s pending flags.
+ * @param FLASH_FLAG: specifies the FLASH flags to clear.
+ * This parameter can be any combination of the following values:
+ * @arg FLASH_FLAG_PGERR: FLASH Program error flag
+ * @arg FLASH_FLAG_WRPRTERR: FLASH Write protected error flag
+ * @arg FLASH_FLAG_EOP: FLASH End of Operation flag
+ * @retval None
+ */
+void FLASH_ClearFlag(uint32_t FLASH_FLAG)
+{
+#ifdef STM32F10X_XL
+ /* Check the parameters */
+ assert_param(IS_FLASH_CLEAR_FLAG(FLASH_FLAG)) ;
+
+ if((FLASH_FLAG & 0x80000000) != 0x0)
+ {
+ /* Clear the flags */
+ FLASH->SR2 = FLASH_FLAG;
+ }
+ else
+ {
+ /* Clear the flags */
+ FLASH->SR = FLASH_FLAG;
+ }
+
+#else
+ /* Check the parameters */
+ assert_param(IS_FLASH_CLEAR_FLAG(FLASH_FLAG)) ;
+
+ /* Clear the flags */
+ FLASH->SR = FLASH_FLAG;
+#endif /* STM32F10X_XL */
+}
+
+/**
+ * @brief Returns the FLASH Status.
+ * @note This function can be used for all STM32F10x devices, it is equivalent
+ * to FLASH_GetBank1Status function.
+ * @param None
+ * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
+ * FLASH_ERROR_WRP or FLASH_COMPLETE
+ */
+FLASH_Status FLASH_GetStatus(void)
+{
+ FLASH_Status flashstatus = FLASH_COMPLETE;
+
+ if((FLASH->SR & FLASH_FLAG_BSY) == FLASH_FLAG_BSY)
+ {
+ flashstatus = FLASH_BUSY;
+ }
+ else
+ {
+ if((FLASH->SR & FLASH_FLAG_PGERR) != 0)
+ {
+ flashstatus = FLASH_ERROR_PG;
+ }
+ else
+ {
+ if((FLASH->SR & FLASH_FLAG_WRPRTERR) != 0 )
+ {
+ flashstatus = FLASH_ERROR_WRP;
+ }
+ else
+ {
+ flashstatus = FLASH_COMPLETE;
+ }
+ }
+ }
+ /* Return the Flash Status */
+ return flashstatus;
+}
+
+/**
+ * @brief Returns the FLASH Bank1 Status.
+ * @note This function can be used for all STM32F10x devices, it is equivalent
+ * to FLASH_GetStatus function.
+ * @param None
+ * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
+ * FLASH_ERROR_WRP or FLASH_COMPLETE
+ */
+FLASH_Status FLASH_GetBank1Status(void)
+{
+ FLASH_Status flashstatus = FLASH_COMPLETE;
+
+ if((FLASH->SR & FLASH_FLAG_BANK1_BSY) == FLASH_FLAG_BSY)
+ {
+ flashstatus = FLASH_BUSY;
+ }
+ else
+ {
+ if((FLASH->SR & FLASH_FLAG_BANK1_PGERR) != 0)
+ {
+ flashstatus = FLASH_ERROR_PG;
+ }
+ else
+ {
+ if((FLASH->SR & FLASH_FLAG_BANK1_WRPRTERR) != 0 )
+ {
+ flashstatus = FLASH_ERROR_WRP;
+ }
+ else
+ {
+ flashstatus = FLASH_COMPLETE;
+ }
+ }
+ }
+ /* Return the Flash Status */
+ return flashstatus;
+}
+
+#ifdef STM32F10X_XL
+/**
+ * @brief Returns the FLASH Bank2 Status.
+ * @note This function can be used for STM32F10x_XL density devices.
+ * @param None
+ * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
+ * FLASH_ERROR_WRP or FLASH_COMPLETE
+ */
+FLASH_Status FLASH_GetBank2Status(void)
+{
+ FLASH_Status flashstatus = FLASH_COMPLETE;
+
+ if((FLASH->SR2 & (FLASH_FLAG_BANK2_BSY & 0x7FFFFFFF)) == (FLASH_FLAG_BANK2_BSY & 0x7FFFFFFF))
+ {
+ flashstatus = FLASH_BUSY;
+ }
+ else
+ {
+ if((FLASH->SR2 & (FLASH_FLAG_BANK2_PGERR & 0x7FFFFFFF)) != 0)
+ {
+ flashstatus = FLASH_ERROR_PG;
+ }
+ else
+ {
+ if((FLASH->SR2 & (FLASH_FLAG_BANK2_WRPRTERR & 0x7FFFFFFF)) != 0 )
+ {
+ flashstatus = FLASH_ERROR_WRP;
+ }
+ else
+ {
+ flashstatus = FLASH_COMPLETE;
+ }
+ }
+ }
+ /* Return the Flash Status */
+ return flashstatus;
+}
+#endif /* STM32F10X_XL */
+/**
+ * @brief Waits for a Flash operation to complete or a TIMEOUT to occur.
+ * @note This function can be used for all STM32F10x devices,
+ * it is equivalent to FLASH_WaitForLastBank1Operation.
+ * - For STM32F10X_XL devices this function waits for a Bank1 Flash operation
+ * to complete or a TIMEOUT to occur.
+ * - For all other devices it waits for a Flash operation to complete
+ * or a TIMEOUT to occur.
+ * @param Timeout: FLASH programming Timeout
+ * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
+ * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
+ */
+FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout)
+{
+ FLASH_Status status = FLASH_COMPLETE;
+
+ /* Check for the Flash Status */
+ status = FLASH_GetBank1Status();
+ /* Wait for a Flash operation to complete or a TIMEOUT to occur */
+ while((status == FLASH_BUSY) && (Timeout != 0x00))
+ {
+ status = FLASH_GetBank1Status();
+ Timeout--;
+ }
+ if(Timeout == 0x00 )
+ {
+ status = FLASH_TIMEOUT;
+ }
+ /* Return the operation status */
+ return status;
+}
+
+/**
+ * @brief Waits for a Flash operation on Bank1 to complete or a TIMEOUT to occur.
+ * @note This function can be used for all STM32F10x devices,
+ * it is equivalent to FLASH_WaitForLastOperation.
+ * @param Timeout: FLASH programming Timeout
+ * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
+ * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
+ */
+FLASH_Status FLASH_WaitForLastBank1Operation(uint32_t Timeout)
+{
+ FLASH_Status status = FLASH_COMPLETE;
+
+ /* Check for the Flash Status */
+ status = FLASH_GetBank1Status();
+ /* Wait for a Flash operation to complete or a TIMEOUT to occur */
+ while((status == FLASH_FLAG_BANK1_BSY) && (Timeout != 0x00))
+ {
+ status = FLASH_GetBank1Status();
+ Timeout--;
+ }
+ if(Timeout == 0x00 )
+ {
+ status = FLASH_TIMEOUT;
+ }
+ /* Return the operation status */
+ return status;
+}
+
+#ifdef STM32F10X_XL
+/**
+ * @brief Waits for a Flash operation on Bank2 to complete or a TIMEOUT to occur.
+ * @note This function can be used only for STM32F10x_XL density devices.
+ * @param Timeout: FLASH programming Timeout
+ * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
+ * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
+ */
+FLASH_Status FLASH_WaitForLastBank2Operation(uint32_t Timeout)
+{
+ FLASH_Status status = FLASH_COMPLETE;
+
+ /* Check for the Flash Status */
+ status = FLASH_GetBank2Status();
+ /* Wait for a Flash operation to complete or a TIMEOUT to occur */
+ while((status == (FLASH_FLAG_BANK2_BSY & 0x7FFFFFFF)) && (Timeout != 0x00))
+ {
+ status = FLASH_GetBank2Status();
+ Timeout--;
+ }
+ if(Timeout == 0x00 )
+ {
+ status = FLASH_TIMEOUT;
+ }
+ /* Return the operation status */
+ return status;
+}
+#endif /* STM32F10X_XL */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_fsmc.c b/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_fsmc.c
new file mode 100644
index 0000000..de73841
--- /dev/null
+++ b/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_fsmc.c
@@ -0,0 +1,872 @@
+/**
+ ******************************************************************************
+ * @file stm32f10x_fsmc.c
+ * @author MCD Application Team
+ * @version V3.6.1
+ * @date 05-March-2012
+ * @brief This file provides all the FSMC firmware functions.
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f10x_i2c.h"
+#include "stm32f10x_rcc.h"
+
+
+/** @addtogroup STM32F10x_StdPeriph_Driver
+ * @{
+ */
+
+/** @defgroup I2C
+ * @brief I2C driver modules
+ * @{
+ */
+
+/** @defgroup I2C_Private_TypesDefinitions
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup I2C_Private_Defines
+ * @{
+ */
+
+/* I2C SPE mask */
+#define CR1_PE_Set ((uint16_t)0x0001)
+#define CR1_PE_Reset ((uint16_t)0xFFFE)
+
+/* I2C START mask */
+#define CR1_START_Set ((uint16_t)0x0100)
+#define CR1_START_Reset ((uint16_t)0xFEFF)
+
+/* I2C STOP mask */
+#define CR1_STOP_Set ((uint16_t)0x0200)
+#define CR1_STOP_Reset ((uint16_t)0xFDFF)
+
+/* I2C ACK mask */
+#define CR1_ACK_Set ((uint16_t)0x0400)
+#define CR1_ACK_Reset ((uint16_t)0xFBFF)
+
+/* I2C ENGC mask */
+#define CR1_ENGC_Set ((uint16_t)0x0040)
+#define CR1_ENGC_Reset ((uint16_t)0xFFBF)
+
+/* I2C SWRST mask */
+#define CR1_SWRST_Set ((uint16_t)0x8000)
+#define CR1_SWRST_Reset ((uint16_t)0x7FFF)
+
+/* I2C PEC mask */
+#define CR1_PEC_Set ((uint16_t)0x1000)
+#define CR1_PEC_Reset ((uint16_t)0xEFFF)
+
+/* I2C ENPEC mask */
+#define CR1_ENPEC_Set ((uint16_t)0x0020)
+#define CR1_ENPEC_Reset ((uint16_t)0xFFDF)
+
+/* I2C ENARP mask */
+#define CR1_ENARP_Set ((uint16_t)0x0010)
+#define CR1_ENARP_Reset ((uint16_t)0xFFEF)
+
+/* I2C NOSTRETCH mask */
+#define CR1_NOSTRETCH_Set ((uint16_t)0x0080)
+#define CR1_NOSTRETCH_Reset ((uint16_t)0xFF7F)
+
+/* I2C registers Masks */
+#define CR1_CLEAR_Mask ((uint16_t)0xFBF5)
+
+/* I2C DMAEN mask */
+#define CR2_DMAEN_Set ((uint16_t)0x0800)
+#define CR2_DMAEN_Reset ((uint16_t)0xF7FF)
+
+/* I2C LAST mask */
+#define CR2_LAST_Set ((uint16_t)0x1000)
+#define CR2_LAST_Reset ((uint16_t)0xEFFF)
+
+/* I2C FREQ mask */
+#define CR2_FREQ_Reset ((uint16_t)0xFFC0)
+
+/* I2C ADD0 mask */
+#define OAR1_ADD0_Set ((uint16_t)0x0001)
+#define OAR1_ADD0_Reset ((uint16_t)0xFFFE)
+
+/* I2C ENDUAL mask */
+#define OAR2_ENDUAL_Set ((uint16_t)0x0001)
+#define OAR2_ENDUAL_Reset ((uint16_t)0xFFFE)
+
+/* I2C ADD2 mask */
+#define OAR2_ADD2_Reset ((uint16_t)0xFF01)
+
+/* I2C F/S mask */
+#define CCR_FS_Set ((uint16_t)0x8000)
+
+/* I2C CCR mask */
+#define CCR_CCR_Set ((uint16_t)0x0FFF)
+
+/* I2C FLAG mask */
+#define FLAG_Mask ((uint32_t)0x00FFFFFF)
+
+/* I2C Interrupt Enable mask */
+#define ITEN_Mask ((uint32_t)0x07000000)
+
+/**
+ * @}
+ */
+
+/** @defgroup I2C_Private_Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup I2C_Private_Variables
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup I2C_Private_FunctionPrototypes
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup I2C_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief Deinitializes the I2Cx peripheral registers to their default reset values.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @retval None
+ */
+void I2C_DeInit(I2C_TypeDef* I2Cx)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+
+ if (I2Cx == I2C1)
+ {
+ /* Enable I2C1 reset state */
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, ENABLE);
+ /* Release I2C1 from reset state */
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, DISABLE);
+ }
+ else
+ {
+ /* Enable I2C2 reset state */
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C2, ENABLE);
+ /* Release I2C2 from reset state */
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C2, DISABLE);
+ }
+}
+
+/**
+ * @brief Initializes the I2Cx peripheral according to the specified
+ * parameters in the I2C_InitStruct.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param I2C_InitStruct: pointer to a I2C_InitTypeDef structure that
+ * contains the configuration information for the specified I2C peripheral.
+ * @retval None
+ */
+void I2C_Init(I2C_TypeDef* I2Cx, I2C_InitTypeDef* I2C_InitStruct)
+{
+ uint16_t tmpreg = 0, freqrange = 0;
+ uint16_t result = 0x04;
+ uint32_t pclk1 = 8000000;
+ RCC_ClocksTypeDef rcc_clocks;
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_I2C_CLOCK_SPEED(I2C_InitStruct->I2C_ClockSpeed));
+ assert_param(IS_I2C_MODE(I2C_InitStruct->I2C_Mode));
+ assert_param(IS_I2C_DUTY_CYCLE(I2C_InitStruct->I2C_DutyCycle));
+ assert_param(IS_I2C_OWN_ADDRESS1(I2C_InitStruct->I2C_OwnAddress1));
+ assert_param(IS_I2C_ACK_STATE(I2C_InitStruct->I2C_Ack));
+ assert_param(IS_I2C_ACKNOWLEDGE_ADDRESS(I2C_InitStruct->I2C_AcknowledgedAddress));
+
+/*---------------------------- I2Cx CR2 Configuration ------------------------*/
+ /* Get the I2Cx CR2 value */
+ tmpreg = I2Cx->CR2;
+ /* Clear frequency FREQ[5:0] bits */
+ tmpreg &= CR2_FREQ_Reset;
+ /* Get pclk1 frequency value */
+ RCC_GetClocksFreq(&rcc_clocks);
+ pclk1 = rcc_clocks.PCLK1_Frequency;
+ /* Set frequency bits depending on pclk1 value */
+ freqrange = (uint16_t)(pclk1 / 1000000);
+ tmpreg |= freqrange;
+ /* Write to I2Cx CR2 */
+ I2Cx->CR2 = tmpreg;
+
+/*---------------------------- I2Cx CCR Configuration ------------------------*/
+ /* Disable the selected I2C peripheral to configure TRISE */
+ I2Cx->CR1 &= CR1_PE_Reset;
+ /* Reset tmpreg value */
+ /* Clear F/S, DUTY and CCR[11:0] bits */
+ tmpreg = 0;
+
+ /* Configure speed in standard mode */
+ if (I2C_InitStruct->I2C_ClockSpeed <= 100000)
+ {
+ /* Standard mode speed calculate */
+ result = (uint16_t)(pclk1 / (I2C_InitStruct->I2C_ClockSpeed << 1));
+ /* Test if CCR value is under 0x4*/
+ if (result < 0x04)
+ {
+ /* Set minimum allowed value */
+ result = 0x04;
+ }
+ /* Set speed value for standard mode */
+ tmpreg |= result;
+ /* Set Maximum Rise Time for standard mode */
+ I2Cx->TRISE = freqrange + 1;
+ }
+ /* Configure speed in fast mode */
+ else /*(I2C_InitStruct->I2C_ClockSpeed <= 400000)*/
+ {
+ if (I2C_InitStruct->I2C_DutyCycle == I2C_DutyCycle_2)
+ {
+ /* Fast mode speed calculate: Tlow/Thigh = 2 */
+ result = (uint16_t)(pclk1 / (I2C_InitStruct->I2C_ClockSpeed * 3));
+ }
+ else /*I2C_InitStruct->I2C_DutyCycle == I2C_DutyCycle_16_9*/
+ {
+ /* Fast mode speed calculate: Tlow/Thigh = 16/9 */
+ result = (uint16_t)(pclk1 / (I2C_InitStruct->I2C_ClockSpeed * 25));
+ /* Set DUTY bit */
+ result |= I2C_DutyCycle_16_9;
+ }
+
+ /* Test if CCR value is under 0x1*/
+ if ((result & CCR_CCR_Set) == 0)
+ {
+ /* Set minimum allowed value */
+ result |= (uint16_t)0x0001;
+ }
+ /* Set speed value and set F/S bit for fast mode */
+ tmpreg |= (uint16_t)(result | CCR_FS_Set);
+ /* Set Maximum Rise Time for fast mode */
+ I2Cx->TRISE = (uint16_t)(((freqrange * (uint16_t)300) / (uint16_t)1000) + (uint16_t)1);
+ }
+
+ /* Write to I2Cx CCR */
+ I2Cx->CCR = tmpreg;
+ /* Enable the selected I2C peripheral */
+ I2Cx->CR1 |= CR1_PE_Set;
+
+/*---------------------------- I2Cx CR1 Configuration ------------------------*/
+ /* Get the I2Cx CR1 value */
+ tmpreg = I2Cx->CR1;
+ /* Clear ACK, SMBTYPE and SMBUS bits */
+ tmpreg &= CR1_CLEAR_Mask;
+ /* Configure I2Cx: mode and acknowledgement */
+ /* Set SMBTYPE and SMBUS bits according to I2C_Mode value */
+ /* Set ACK bit according to I2C_Ack value */
+ tmpreg |= (uint16_t)((uint32_t)I2C_InitStruct->I2C_Mode | I2C_InitStruct->I2C_Ack);
+ /* Write to I2Cx CR1 */
+ I2Cx->CR1 = tmpreg;
+
+/*---------------------------- I2Cx OAR1 Configuration -----------------------*/
+ /* Set I2Cx Own Address1 and acknowledged address */
+ I2Cx->OAR1 = (I2C_InitStruct->I2C_AcknowledgedAddress | I2C_InitStruct->I2C_OwnAddress1);
+}
+
+/**
+ * @brief Fills each I2C_InitStruct member with its default value.
+ * @param I2C_InitStruct: pointer to an I2C_InitTypeDef structure which will be initialized.
+ * @retval None
+ */
+void I2C_StructInit(I2C_InitTypeDef* I2C_InitStruct)
+{
+/*---------------- Reset I2C init structure parameters values ----------------*/
+ /* initialize the I2C_ClockSpeed member */
+ I2C_InitStruct->I2C_ClockSpeed = 5000;
+ /* Initialize the I2C_Mode member */
+ I2C_InitStruct->I2C_Mode = I2C_Mode_I2C;
+ /* Initialize the I2C_DutyCycle member */
+ I2C_InitStruct->I2C_DutyCycle = I2C_DutyCycle_2;
+ /* Initialize the I2C_OwnAddress1 member */
+ I2C_InitStruct->I2C_OwnAddress1 = 0;
+ /* Initialize the I2C_Ack member */
+ I2C_InitStruct->I2C_Ack = I2C_Ack_Disable;
+ /* Initialize the I2C_AcknowledgedAddress member */
+ I2C_InitStruct->I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
+}
+
+/**
+ * @brief Enables or disables the specified I2C peripheral.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param NewState: new state of the I2Cx peripheral.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void I2C_Cmd(I2C_TypeDef* I2Cx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected I2C peripheral */
+ I2Cx->CR1 |= CR1_PE_Set;
+ }
+ else
+ {
+ /* Disable the selected I2C peripheral */
+ I2Cx->CR1 &= CR1_PE_Reset;
+ }
+}
+
+/**
+ * @brief Enables or disables the specified I2C DMA requests.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param NewState: new state of the I2C DMA transfer.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void I2C_DMACmd(I2C_TypeDef* I2Cx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected I2C DMA requests */
+ I2Cx->CR2 |= CR2_DMAEN_Set;
+ }
+ else
+ {
+ /* Disable the selected I2C DMA requests */
+ I2Cx->CR2 &= CR2_DMAEN_Reset;
+ }
+}
+
+/**
+ * @brief Specifies if the next DMA transfer will be the last one.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param NewState: new state of the I2C DMA last transfer.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void I2C_DMALastTransferCmd(I2C_TypeDef* I2Cx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Next DMA transfer is the last transfer */
+ I2Cx->CR2 |= CR2_LAST_Set;
+ }
+ else
+ {
+ /* Next DMA transfer is not the last transfer */
+ I2Cx->CR2 &= CR2_LAST_Reset;
+ }
+}
+
+/**
+ * @brief Generates I2Cx communication START condition.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param NewState: new state of the I2C START condition generation.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None.
+ */
+void I2C_GenerateSTART(I2C_TypeDef* I2Cx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Generate a START condition */
+ I2Cx->CR1 |= CR1_START_Set;
+ }
+ else
+ {
+ /* Disable the START condition generation */
+ I2Cx->CR1 &= CR1_START_Reset;
+ }
+}
+
+/**
+ * @brief Generates I2Cx communication STOP condition.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param NewState: new state of the I2C STOP condition generation.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None.
+ */
+void I2C_GenerateSTOP(I2C_TypeDef* I2Cx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Generate a STOP condition */
+ I2Cx->CR1 |= CR1_STOP_Set;
+ }
+ else
+ {
+ /* Disable the STOP condition generation */
+ I2Cx->CR1 &= CR1_STOP_Reset;
+ }
+}
+
+/**
+ * @brief Enables or disables the specified I2C acknowledge feature.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param NewState: new state of the I2C Acknowledgement.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None.
+ */
+void I2C_AcknowledgeConfig(I2C_TypeDef* I2Cx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Enable the acknowledgement */
+ I2Cx->CR1 |= CR1_ACK_Set;
+ }
+ else
+ {
+ /* Disable the acknowledgement */
+ I2Cx->CR1 &= CR1_ACK_Reset;
+ }
+}
+
+/**
+ * @brief Configures the specified I2C own address2.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param Address: specifies the 7bit I2C own address2.
+ * @retval None.
+ */
+void I2C_OwnAddress2Config(I2C_TypeDef* I2Cx, uint8_t Address)
+{
+ uint16_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+
+ /* Get the old register value */
+ tmpreg = I2Cx->OAR2;
+
+ /* Reset I2Cx Own address2 bit [7:1] */
+ tmpreg &= OAR2_ADD2_Reset;
+
+ /* Set I2Cx Own address2 */
+ tmpreg |= (uint16_t)((uint16_t)Address & (uint16_t)0x00FE);
+
+ /* Store the new register value */
+ I2Cx->OAR2 = tmpreg;
+}
+
+/**
+ * @brief Enables or disables the specified I2C dual addressing mode.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param NewState: new state of the I2C dual addressing mode.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void I2C_DualAddressCmd(I2C_TypeDef* I2Cx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Enable dual addressing mode */
+ I2Cx->OAR2 |= OAR2_ENDUAL_Set;
+ }
+ else
+ {
+ /* Disable dual addressing mode */
+ I2Cx->OAR2 &= OAR2_ENDUAL_Reset;
+ }
+}
+
+/**
+ * @brief Enables or disables the specified I2C general call feature.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param NewState: new state of the I2C General call.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void I2C_GeneralCallCmd(I2C_TypeDef* I2Cx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Enable generall call */
+ I2Cx->CR1 |= CR1_ENGC_Set;
+ }
+ else
+ {
+ /* Disable generall call */
+ I2Cx->CR1 &= CR1_ENGC_Reset;
+ }
+}
+
+/**
+ * @brief Enables or disables the specified I2C interrupts.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param I2C_IT: specifies the I2C interrupts sources to be enabled or disabled.
+ * This parameter can be any combination of the following values:
+ * @arg I2C_IT_BUF: Buffer interrupt mask
+ * @arg I2C_IT_EVT: Event interrupt mask
+ * @arg I2C_IT_ERR: Error interrupt mask
+ * @param NewState: new state of the specified I2C interrupts.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void I2C_ITConfig(I2C_TypeDef* I2Cx, uint16_t I2C_IT, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ assert_param(IS_I2C_CONFIG_IT(I2C_IT));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected I2C interrupts */
+ I2Cx->CR2 |= I2C_IT;
+ }
+ else
+ {
+ /* Disable the selected I2C interrupts */
+ I2Cx->CR2 &= (uint16_t)~I2C_IT;
+ }
+}
+
+/**
+ * @brief Sends a data byte through the I2Cx peripheral.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param Data: Byte to be transmitted..
+ * @retval None
+ */
+void I2C_SendData(I2C_TypeDef* I2Cx, uint8_t Data)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ /* Write in the DR register the data to be sent */
+ I2Cx->DR = Data;
+}
+
+/**
+ * @brief Returns the most recent received data by the I2Cx peripheral.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @retval The value of the received data.
+ */
+uint8_t I2C_ReceiveData(I2C_TypeDef* I2Cx)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ /* Return the data in the DR register */
+ return (uint8_t)I2Cx->DR;
+}
+
+/**
+ * @brief Transmits the address byte to select the slave device.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param Address: specifies the slave address which will be transmitted
+ * @param I2C_Direction: specifies whether the I2C device will be a
+ * Transmitter or a Receiver. This parameter can be one of the following values
+ * @arg I2C_Direction_Transmitter: Transmitter mode
+ * @arg I2C_Direction_Receiver: Receiver mode
+ * @retval None.
+ */
+void I2C_Send7bitAddress(I2C_TypeDef* I2Cx, uint8_t Address, uint8_t I2C_Direction)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_I2C_DIRECTION(I2C_Direction));
+ /* Test on the direction to set/reset the read/write bit */
+ if (I2C_Direction != I2C_Direction_Transmitter)
+ {
+ /* Set the address bit0 for read */
+ Address |= OAR1_ADD0_Set;
+ }
+ else
+ {
+ /* Reset the address bit0 for write */
+ Address &= OAR1_ADD0_Reset;
+ }
+ /* Send the address */
+ I2Cx->DR = Address;
+}
+
+/**
+ * @brief Reads the specified I2C register and returns its value.
+ * @param I2C_Register: specifies the register to read.
+ * This parameter can be one of the following values:
+ * @arg I2C_Register_CR1: CR1 register.
+ * @arg I2C_Register_CR2: CR2 register.
+ * @arg I2C_Register_OAR1: OAR1 register.
+ * @arg I2C_Register_OAR2: OAR2 register.
+ * @arg I2C_Register_DR: DR register.
+ * @arg I2C_Register_SR1: SR1 register.
+ * @arg I2C_Register_SR2: SR2 register.
+ * @arg I2C_Register_CCR: CCR register.
+ * @arg I2C_Register_TRISE: TRISE register.
+ * @retval The value of the read register.
+ */
+uint16_t I2C_ReadRegister(I2C_TypeDef* I2Cx, uint8_t I2C_Register)
+{
+ __IO uint32_t tmp = 0;
+
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_I2C_REGISTER(I2C_Register));
+
+ tmp = (uint32_t) I2Cx;
+ tmp += I2C_Register;
+
+ /* Return the selected register value */
+ return (*(__IO uint16_t *) tmp);
+}
+
+/**
+ * @brief Enables or disables the specified I2C software reset.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param NewState: new state of the I2C software reset.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void I2C_SoftwareResetCmd(I2C_TypeDef* I2Cx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Peripheral under reset */
+ I2Cx->CR1 |= CR1_SWRST_Set;
+ }
+ else
+ {
+ /* Peripheral not under reset */
+ I2Cx->CR1 &= CR1_SWRST_Reset;
+ }
+}
+
+/**
+ * @brief Selects the specified I2C NACK position in master receiver mode.
+ * This function is useful in I2C Master Receiver mode when the number
+ * of data to be received is equal to 2. In this case, this function
+ * should be called (with parameter I2C_NACKPosition_Next) before data
+ * reception starts,as described in the 2-byte reception procedure
+ * recommended in Reference Manual in Section: Master receiver.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param I2C_NACKPosition: specifies the NACK position.
+ * This parameter can be one of the following values:
+ * @arg I2C_NACKPosition_Next: indicates that the next byte will be the last
+ * received byte.
+ * @arg I2C_NACKPosition_Current: indicates that current byte is the last
+ * received byte.
+ *
+ * @note This function configures the same bit (POS) as I2C_PECPositionConfig()
+ * but is intended to be used in I2C mode while I2C_PECPositionConfig()
+ * is intended to used in SMBUS mode.
+ *
+ * @retval None
+ */
+void I2C_NACKPositionConfig(I2C_TypeDef* I2Cx, uint16_t I2C_NACKPosition)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_I2C_NACK_POSITION(I2C_NACKPosition));
+
+ /* Check the input parameter */
+ if (I2C_NACKPosition == I2C_NACKPosition_Next)
+ {
+ /* Next byte in shift register is the last received byte */
+ I2Cx->CR1 |= I2C_NACKPosition_Next;
+ }
+ else
+ {
+ /* Current byte in shift register is the last received byte */
+ I2Cx->CR1 &= I2C_NACKPosition_Current;
+ }
+}
+
+/**
+ * @brief Drives the SMBusAlert pin high or low for the specified I2C.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param I2C_SMBusAlert: specifies SMBAlert pin level.
+ * This parameter can be one of the following values:
+ * @arg I2C_SMBusAlert_Low: SMBAlert pin driven low
+ * @arg I2C_SMBusAlert_High: SMBAlert pin driven high
+ * @retval None
+ */
+void I2C_SMBusAlertConfig(I2C_TypeDef* I2Cx, uint16_t I2C_SMBusAlert)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_I2C_SMBUS_ALERT(I2C_SMBusAlert));
+ if (I2C_SMBusAlert == I2C_SMBusAlert_Low)
+ {
+ /* Drive the SMBusAlert pin Low */
+ I2Cx->CR1 |= I2C_SMBusAlert_Low;
+ }
+ else
+ {
+ /* Drive the SMBusAlert pin High */
+ I2Cx->CR1 &= I2C_SMBusAlert_High;
+ }
+}
+
+/**
+ * @brief Enables or disables the specified I2C PEC transfer.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param NewState: new state of the I2C PEC transmission.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void I2C_TransmitPEC(I2C_TypeDef* I2Cx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected I2C PEC transmission */
+ I2Cx->CR1 |= CR1_PEC_Set;
+ }
+ else
+ {
+ /* Disable the selected I2C PEC transmission */
+ I2Cx->CR1 &= CR1_PEC_Reset;
+ }
+}
+
+/**
+ * @brief Selects the specified I2C PEC position.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param I2C_PECPosition: specifies the PEC position.
+ * This parameter can be one of the following values:
+ * @arg I2C_PECPosition_Next: indicates that the next byte is PEC
+ * @arg I2C_PECPosition_Current: indicates that current byte is PEC
+ *
+ * @note This function configures the same bit (POS) as I2C_NACKPositionConfig()
+ * but is intended to be used in SMBUS mode while I2C_NACKPositionConfig()
+ * is intended to used in I2C mode.
+ *
+ * @retval None
+ */
+void I2C_PECPositionConfig(I2C_TypeDef* I2Cx, uint16_t I2C_PECPosition)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_I2C_PEC_POSITION(I2C_PECPosition));
+ if (I2C_PECPosition == I2C_PECPosition_Next)
+ {
+ /* Next byte in shift register is PEC */
+ I2Cx->CR1 |= I2C_PECPosition_Next;
+ }
+ else
+ {
+ /* Current byte in shift register is PEC */
+ I2Cx->CR1 &= I2C_PECPosition_Current;
+ }
+}
+
+/**
+ * @brief Enables or disables the PEC value calculation of the transferred bytes.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param NewState: new state of the I2Cx PEC value calculation.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void I2C_CalculatePEC(I2C_TypeDef* I2Cx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected I2C PEC calculation */
+ I2Cx->CR1 |= CR1_ENPEC_Set;
+ }
+ else
+ {
+ /* Disable the selected I2C PEC calculation */
+ I2Cx->CR1 &= CR1_ENPEC_Reset;
+ }
+}
+
+/**
+ * @brief Returns the PEC value for the specified I2C.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @retval The PEC value.
+ */
+uint8_t I2C_GetPEC(I2C_TypeDef* I2Cx)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ /* Return the selected I2C PEC value */
+ return ((I2Cx->SR2) >> 8);
+}
+
+/**
+ * @brief Enables or disables the specified I2C ARP.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param NewState: new state of the I2Cx ARP.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void I2C_ARPCmd(I2C_TypeDef* I2Cx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected I2C ARP */
+ I2Cx->CR1 |= CR1_ENARP_Set;
+ }
+ else
+ {
+ /* Disable the selected I2C ARP */
+ I2Cx->CR1 &= CR1_ENARP_Reset;
+ }
+}
+
+/**
+ * @brief Enables or disables the specified I2C Clock stretching.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param NewState: new state of the I2Cx Clock stretching.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void I2C_StretchClockCmd(I2C_TypeDef* I2Cx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState == DISABLE)
+ {
+ /* Enable the selected I2C Clock stretching */
+ I2Cx->CR1 |= CR1_NOSTRETCH_Set;
+ }
+ else
+ {
+ /* Disable the selected I2C Clock stretching */
+ I2Cx->CR1 &= CR1_NOSTRETCH_Reset;
+ }
+}
+
+/**
+ * @brief Selects the specified I2C fast mode duty cycle.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param I2C_DutyCycle: specifies the fast mode duty cycle.
+ * This parameter can be one of the following values:
+ * @arg I2C_DutyCycle_2: I2C fast mode Tlow/Thigh = 2
+ * @arg I2C_DutyCycle_16_9: I2C fast mode Tlow/Thigh = 16/9
+ * @retval None
+ */
+void I2C_FastModeDutyCycleConfig(I2C_TypeDef* I2Cx, uint16_t I2C_DutyCycle)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_I2C_DUTY_CYCLE(I2C_DutyCycle));
+ if (I2C_DutyCycle != I2C_DutyCycle_16_9)
+ {
+ /* I2C fast mode Tlow/Thigh=2 */
+ I2Cx->CCR &= I2C_DutyCycle_2;
+ }
+ else
+ {
+ /* I2C fast mode Tlow/Thigh=16/9 */
+ I2Cx->CCR |= I2C_DutyCycle_16_9;
+ }
+}
+
+
+
+/**
+ * @brief
+ ****************************************************************************************
+ *
+ * I2C State Monitoring Functions
+ *
+ ****************************************************************************************
+ * This I2C driver provides three different ways for I2C state monitoring
+ * depending on the application requirements and constraints:
+ *
+ *
+ * 1) Basic state monitoring:
+ * Using I2C_CheckEvent() function:
+ * It compares the status registers (SR1 and SR2) content to a given event
+ * (can be the combination of one or more flags).
+ * It returns SUCCESS if the current status includes the given flags
+ * and returns ERROR if one or more flags are missing in the current status.
+ * - When to use:
+ * - This function is suitable for most applications as well as for startup
+ * activity since the events are fully described in the product reference manual
+ * (RM0008).
+ * - It is also suitable for users who need to define their own events.
+ * - Limitations:
+ * - If an error occurs (ie. error flags are set besides to the monitored flags),
+ * the I2C_CheckEvent() function may return SUCCESS despite the communication
+ * hold or corrupted real state.
+ * In this case, it is advised to use error interrupts to monitor the error
+ * events and handle them in the interrupt IRQ handler.
+ *
+ * @note
+ * For error management, it is advised to use the following functions:
+ * - I2C_ITConfig() to configure and enable the error interrupts (I2C_IT_ERR).
+ * - I2Cx_ER_IRQHandler() which is called when the error interrupt occurs.
+ * Where x is the peripheral instance (I2C1, I2C2 ...)
+ * - I2C_GetFlagStatus() or I2C_GetITStatus() to be called into I2Cx_ER_IRQHandler()
+ * in order to determine which error occured.
+ * - I2C_ClearFlag() or I2C_ClearITPendingBit() and/or I2C_SoftwareResetCmd()
+ * and/or I2C_GenerateStop() in order to clear the error flag and source,
+ * and return to correct communication status.
+ *
+ *
+ * 2) Advanced state monitoring:
+ * Using the function I2C_GetLastEvent() which returns the image of both status
+ * registers in a single word (uint32_t) (Status Register 2 value is shifted left
+ * by 16 bits and concatenated to Status Register 1).
+ * - When to use:
+ * - This function is suitable for the same applications above but it allows to
+ * overcome the mentioned limitation of I2C_GetFlagStatus() function.
+ * The returned value could be compared to events already defined in the
+ * library (stm32f10x_i2c.h) or to custom values defined by user.
+ * - This function is suitable when multiple flags are monitored at the same time.
+ * - At the opposite of I2C_CheckEvent() function, this function allows user to
+ * choose when an event is accepted (when all events flags are set and no
+ * other flags are set or just when the needed flags are set like
+ * I2C_CheckEvent() function).
+ * - Limitations:
+ * - User may need to define his own events.
+ * - Same remark concerning the error management is applicable for this
+ * function if user decides to check only regular communication flags (and
+ * ignores error flags).
+ *
+ *
+ * 3) Flag-based state monitoring:
+ * Using the function I2C_GetFlagStatus() which simply returns the status of
+ * one single flag (ie. I2C_FLAG_RXNE ...).
+ * - When to use:
+ * - This function could be used for specific applications or in debug phase.
+ * - It is suitable when only one flag checking is needed (most I2C events
+ * are monitored through multiple flags).
+ * - Limitations:
+ * - When calling this function, the Status register is accessed. Some flags are
+ * cleared when the status register is accessed. So checking the status
+ * of one Flag, may clear other ones.
+ * - Function may need to be called twice or more in order to monitor one
+ * single event.
+ *
+ * For detailed description of Events, please refer to section I2C_Events in
+ * stm32f10x_i2c.h file.
+ *
+ */
+
+/**
+ *
+ * 1) Basic state monitoring
+ *******************************************************************************
+ */
+
+/**
+ * @brief Checks whether the last I2Cx Event is equal to the one passed
+ * as parameter.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param I2C_EVENT: specifies the event to be checked.
+ * This parameter can be one of the following values:
+ * @arg I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED : EV1
+ * @arg I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED : EV1
+ * @arg I2C_EVENT_SLAVE_TRANSMITTER_SECONDADDRESS_MATCHED : EV1
+ * @arg I2C_EVENT_SLAVE_RECEIVER_SECONDADDRESS_MATCHED : EV1
+ * @arg I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED : EV1
+ * @arg I2C_EVENT_SLAVE_BYTE_RECEIVED : EV2
+ * @arg (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_DUALF) : EV2
+ * @arg (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_GENCALL) : EV2
+ * @arg I2C_EVENT_SLAVE_BYTE_TRANSMITTED : EV3
+ * @arg (I2C_EVENT_SLAVE_BYTE_TRANSMITTED | I2C_FLAG_DUALF) : EV3
+ * @arg (I2C_EVENT_SLAVE_BYTE_TRANSMITTED | I2C_FLAG_GENCALL) : EV3
+ * @arg I2C_EVENT_SLAVE_ACK_FAILURE : EV3_2
+ * @arg I2C_EVENT_SLAVE_STOP_DETECTED : EV4
+ * @arg I2C_EVENT_MASTER_MODE_SELECT : EV5
+ * @arg I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED : EV6
+ * @arg I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED : EV6
+ * @arg I2C_EVENT_MASTER_BYTE_RECEIVED : EV7
+ * @arg I2C_EVENT_MASTER_BYTE_TRANSMITTING : EV8
+ * @arg I2C_EVENT_MASTER_BYTE_TRANSMITTED : EV8_2
+ * @arg I2C_EVENT_MASTER_MODE_ADDRESS10 : EV9
+ *
+ * @note: For detailed description of Events, please refer to section
+ * I2C_Events in stm32f10x_i2c.h file.
+ *
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: Last event is equal to the I2C_EVENT
+ * - ERROR: Last event is different from the I2C_EVENT
+ */
+ErrorStatus I2C_CheckEvent(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT)
+{
+ uint32_t lastevent = 0;
+ uint32_t flag1 = 0, flag2 = 0;
+ ErrorStatus status = ERROR;
+
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_I2C_EVENT(I2C_EVENT));
+
+ /* Read the I2Cx status register */
+ flag1 = I2Cx->SR1;
+ flag2 = I2Cx->SR2;
+ flag2 = flag2 << 16;
+
+ /* Get the last event value from I2C status register */
+ lastevent = (flag1 | flag2) & FLAG_Mask;
+
+ /* Check whether the last event contains the I2C_EVENT */
+ if ((lastevent & I2C_EVENT) == I2C_EVENT)
+ {
+ /* SUCCESS: last event is equal to I2C_EVENT */
+ status = SUCCESS;
+ }
+ else
+ {
+ /* ERROR: last event is different from I2C_EVENT */
+ status = ERROR;
+ }
+ /* Return status */
+ return status;
+}
+
+/**
+ *
+ * 2) Advanced state monitoring
+ *******************************************************************************
+ */
+
+/**
+ * @brief Returns the last I2Cx Event.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ *
+ * @note: For detailed description of Events, please refer to section
+ * I2C_Events in stm32f10x_i2c.h file.
+ *
+ * @retval The last event
+ */
+uint32_t I2C_GetLastEvent(I2C_TypeDef* I2Cx)
+{
+ uint32_t lastevent = 0;
+ uint32_t flag1 = 0, flag2 = 0;
+
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+
+ /* Read the I2Cx status register */
+ flag1 = I2Cx->SR1;
+ flag2 = I2Cx->SR2;
+ flag2 = flag2 << 16;
+
+ /* Get the last event value from I2C status register */
+ lastevent = (flag1 | flag2) & FLAG_Mask;
+
+ /* Return status */
+ return lastevent;
+}
+
+/**
+ *
+ * 3) Flag-based state monitoring
+ *******************************************************************************
+ */
+
+/**
+ * @brief Checks whether the specified I2C flag is set or not.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param I2C_FLAG: specifies the flag to check.
+ * This parameter can be one of the following values:
+ * @arg I2C_FLAG_DUALF: Dual flag (Slave mode)
+ * @arg I2C_FLAG_SMBHOST: SMBus host header (Slave mode)
+ * @arg I2C_FLAG_SMBDEFAULT: SMBus default header (Slave mode)
+ * @arg I2C_FLAG_GENCALL: General call header flag (Slave mode)
+ * @arg I2C_FLAG_TRA: Transmitter/Receiver flag
+ * @arg I2C_FLAG_BUSY: Bus busy flag
+ * @arg I2C_FLAG_MSL: Master/Slave flag
+ * @arg I2C_FLAG_SMBALERT: SMBus Alert flag
+ * @arg I2C_FLAG_TIMEOUT: Timeout or Tlow error flag
+ * @arg I2C_FLAG_PECERR: PEC error in reception flag
+ * @arg I2C_FLAG_OVR: Overrun/Underrun flag (Slave mode)
+ * @arg I2C_FLAG_AF: Acknowledge failure flag
+ * @arg I2C_FLAG_ARLO: Arbitration lost flag (Master mode)
+ * @arg I2C_FLAG_BERR: Bus error flag
+ * @arg I2C_FLAG_TXE: Data register empty flag (Transmitter)
+ * @arg I2C_FLAG_RXNE: Data register not empty (Receiver) flag
+ * @arg I2C_FLAG_STOPF: Stop detection flag (Slave mode)
+ * @arg I2C_FLAG_ADD10: 10-bit header sent flag (Master mode)
+ * @arg I2C_FLAG_BTF: Byte transfer finished flag
+ * @arg I2C_FLAG_ADDR: Address sent flag (Master mode) "ADSL"
+ * Address matched flag (Slave mode)"ENDA"
+ * @arg I2C_FLAG_SB: Start bit flag (Master mode)
+ * @retval The new state of I2C_FLAG (SET or RESET).
+ */
+FlagStatus I2C_GetFlagStatus(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG)
+{
+ FlagStatus bitstatus = RESET;
+ __IO uint32_t i2creg = 0, i2cxbase = 0;
+
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_I2C_GET_FLAG(I2C_FLAG));
+
+ /* Get the I2Cx peripheral base address */
+ i2cxbase = (uint32_t)I2Cx;
+
+ /* Read flag register index */
+ i2creg = I2C_FLAG >> 28;
+
+ /* Get bit[23:0] of the flag */
+ I2C_FLAG &= FLAG_Mask;
+
+ if(i2creg != 0)
+ {
+ /* Get the I2Cx SR1 register address */
+ i2cxbase += 0x14;
+ }
+ else
+ {
+ /* Flag in I2Cx SR2 Register */
+ I2C_FLAG = (uint32_t)(I2C_FLAG >> 16);
+ /* Get the I2Cx SR2 register address */
+ i2cxbase += 0x18;
+ }
+
+ if(((*(__IO uint32_t *)i2cxbase) & I2C_FLAG) != (uint32_t)RESET)
+ {
+ /* I2C_FLAG is set */
+ bitstatus = SET;
+ }
+ else
+ {
+ /* I2C_FLAG is reset */
+ bitstatus = RESET;
+ }
+
+ /* Return the I2C_FLAG status */
+ return bitstatus;
+}
+
+
+
+/**
+ * @brief Clears the I2Cx's pending flags.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param I2C_FLAG: specifies the flag to clear.
+ * This parameter can be any combination of the following values:
+ * @arg I2C_FLAG_SMBALERT: SMBus Alert flag
+ * @arg I2C_FLAG_TIMEOUT: Timeout or Tlow error flag
+ * @arg I2C_FLAG_PECERR: PEC error in reception flag
+ * @arg I2C_FLAG_OVR: Overrun/Underrun flag (Slave mode)
+ * @arg I2C_FLAG_AF: Acknowledge failure flag
+ * @arg I2C_FLAG_ARLO: Arbitration lost flag (Master mode)
+ * @arg I2C_FLAG_BERR: Bus error flag
+ *
+ * @note
+ * - STOPF (STOP detection) is cleared by software sequence: a read operation
+ * to I2C_SR1 register (I2C_GetFlagStatus()) followed by a write operation
+ * to I2C_CR1 register (I2C_Cmd() to re-enable the I2C peripheral).
+ * - ADD10 (10-bit header sent) is cleared by software sequence: a read
+ * operation to I2C_SR1 (I2C_GetFlagStatus()) followed by writing the
+ * second byte of the address in DR register.
+ * - BTF (Byte Transfer Finished) is cleared by software sequence: a read
+ * operation to I2C_SR1 register (I2C_GetFlagStatus()) followed by a
+ * read/write to I2C_DR register (I2C_SendData()).
+ * - ADDR (Address sent) is cleared by software sequence: a read operation to
+ * I2C_SR1 register (I2C_GetFlagStatus()) followed by a read operation to
+ * I2C_SR2 register ((void)(I2Cx->SR2)).
+ * - SB (Start Bit) is cleared software sequence: a read operation to I2C_SR1
+ * register (I2C_GetFlagStatus()) followed by a write operation to I2C_DR
+ * register (I2C_SendData()).
+ * @retval None
+ */
+void I2C_ClearFlag(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG)
+{
+ uint32_t flagpos = 0;
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_I2C_CLEAR_FLAG(I2C_FLAG));
+ /* Get the I2C flag position */
+ flagpos = I2C_FLAG & FLAG_Mask;
+ /* Clear the selected I2C flag */
+ I2Cx->SR1 = (uint16_t)~flagpos;
+}
+
+/**
+ * @brief Checks whether the specified I2C interrupt has occurred or not.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param I2C_IT: specifies the interrupt source to check.
+ * This parameter can be one of the following values:
+ * @arg I2C_IT_SMBALERT: SMBus Alert flag
+ * @arg I2C_IT_TIMEOUT: Timeout or Tlow error flag
+ * @arg I2C_IT_PECERR: PEC error in reception flag
+ * @arg I2C_IT_OVR: Overrun/Underrun flag (Slave mode)
+ * @arg I2C_IT_AF: Acknowledge failure flag
+ * @arg I2C_IT_ARLO: Arbitration lost flag (Master mode)
+ * @arg I2C_IT_BERR: Bus error flag
+ * @arg I2C_IT_TXE: Data register empty flag (Transmitter)
+ * @arg I2C_IT_RXNE: Data register not empty (Receiver) flag
+ * @arg I2C_IT_STOPF: Stop detection flag (Slave mode)
+ * @arg I2C_IT_ADD10: 10-bit header sent flag (Master mode)
+ * @arg I2C_IT_BTF: Byte transfer finished flag
+ * @arg I2C_IT_ADDR: Address sent flag (Master mode) "ADSL"
+ * Address matched flag (Slave mode)"ENDAD"
+ * @arg I2C_IT_SB: Start bit flag (Master mode)
+ * @retval The new state of I2C_IT (SET or RESET).
+ */
+ITStatus I2C_GetITStatus(I2C_TypeDef* I2Cx, uint32_t I2C_IT)
+{
+ ITStatus bitstatus = RESET;
+ uint32_t enablestatus = 0;
+
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_I2C_GET_IT(I2C_IT));
+
+ /* Check if the interrupt source is enabled or not */
+ enablestatus = (uint32_t)(((I2C_IT & ITEN_Mask) >> 16) & (I2Cx->CR2)) ;
+
+ /* Get bit[23:0] of the flag */
+ I2C_IT &= FLAG_Mask;
+
+ /* Check the status of the specified I2C flag */
+ if (((I2Cx->SR1 & I2C_IT) != (uint32_t)RESET) && enablestatus)
+ {
+ /* I2C_IT is set */
+ bitstatus = SET;
+ }
+ else
+ {
+ /* I2C_IT is reset */
+ bitstatus = RESET;
+ }
+ /* Return the I2C_IT status */
+ return bitstatus;
+}
+
+/**
+ * @brief Clears the I2Cx�s interrupt pending bits.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param I2C_IT: specifies the interrupt pending bit to clear.
+ * This parameter can be any combination of the following values:
+ * @arg I2C_IT_SMBALERT: SMBus Alert interrupt
+ * @arg I2C_IT_TIMEOUT: Timeout or Tlow error interrupt
+ * @arg I2C_IT_PECERR: PEC error in reception interrupt
+ * @arg I2C_IT_OVR: Overrun/Underrun interrupt (Slave mode)
+ * @arg I2C_IT_AF: Acknowledge failure interrupt
+ * @arg I2C_IT_ARLO: Arbitration lost interrupt (Master mode)
+ * @arg I2C_IT_BERR: Bus error interrupt
+ *
+ * @note
+ * - STOPF (STOP detection) is cleared by software sequence: a read operation
+ * to I2C_SR1 register (I2C_GetITStatus()) followed by a write operation to
+ * I2C_CR1 register (I2C_Cmd() to re-enable the I2C peripheral).
+ * - ADD10 (10-bit header sent) is cleared by software sequence: a read
+ * operation to I2C_SR1 (I2C_GetITStatus()) followed by writing the second
+ * byte of the address in I2C_DR register.
+ * - BTF (Byte Transfer Finished) is cleared by software sequence: a read
+ * operation to I2C_SR1 register (I2C_GetITStatus()) followed by a
+ * read/write to I2C_DR register (I2C_SendData()).
+ * - ADDR (Address sent) is cleared by software sequence: a read operation to
+ * I2C_SR1 register (I2C_GetITStatus()) followed by a read operation to
+ * I2C_SR2 register ((void)(I2Cx->SR2)).
+ * - SB (Start Bit) is cleared by software sequence: a read operation to
+ * I2C_SR1 register (I2C_GetITStatus()) followed by a write operation to
+ * I2C_DR register (I2C_SendData()).
+ * @retval None
+ */
+void I2C_ClearITPendingBit(I2C_TypeDef* I2Cx, uint32_t I2C_IT)
+{
+ uint32_t flagpos = 0;
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_I2C_CLEAR_IT(I2C_IT));
+ /* Get the I2C flag position */
+ flagpos = I2C_IT & FLAG_Mask;
+ /* Clear the selected I2C flag */
+ I2Cx->SR1 = (uint16_t)~flagpos;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_iwdg.c b/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_iwdg.c
new file mode 100644
index 0000000..498d491
--- /dev/null
+++ b/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_iwdg.c
@@ -0,0 +1,196 @@
+/**
+ ******************************************************************************
+ * @file stm32f10x_iwdg.c
+ * @author MCD Application Team
+ * @version V3.6.1
+ * @date 05-March-2012
+ * @brief This file provides all the IWDG firmware functions.
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f10x_tim.h"
+#include "stm32f10x_rcc.h"
+
+/** @addtogroup STM32F10x_StdPeriph_Driver
+ * @{
+ */
+
+/** @defgroup TIM
+ * @brief TIM driver modules
+ * @{
+ */
+
+/** @defgroup TIM_Private_TypesDefinitions
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Private_Defines
+ * @{
+ */
+
+/* ---------------------- TIM registers bit mask ------------------------ */
+#define SMCR_ETR_Mask ((uint16_t)0x00FF)
+#define CCMR_Offset ((uint16_t)0x0018)
+#define CCER_CCE_Set ((uint16_t)0x0001)
+#define CCER_CCNE_Set ((uint16_t)0x0004)
+
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Private_Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Private_Variables
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Private_FunctionPrototypes
+ * @{
+ */
+
+static void TI1_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection,
+ uint16_t TIM_ICFilter);
+static void TI2_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection,
+ uint16_t TIM_ICFilter);
+static void TI3_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection,
+ uint16_t TIM_ICFilter);
+static void TI4_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection,
+ uint16_t TIM_ICFilter);
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Private_Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Private_Variables
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Private_FunctionPrototypes
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief Deinitializes the TIMx peripheral registers to their default reset values.
+ * @param TIMx: where x can be 1 to 17 to select the TIM peripheral.
+ * @retval None
+ */
+void TIM_DeInit(TIM_TypeDef* TIMx)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+
+ if (TIMx == TIM1)
+ {
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM1, ENABLE);
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM1, DISABLE);
+ }
+ else if (TIMx == TIM2)
+ {
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM2, ENABLE);
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM2, DISABLE);
+ }
+ else if (TIMx == TIM3)
+ {
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM3, ENABLE);
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM3, DISABLE);
+ }
+ else if (TIMx == TIM4)
+ {
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM4, ENABLE);
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM4, DISABLE);
+ }
+ else if (TIMx == TIM5)
+ {
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM5, ENABLE);
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM5, DISABLE);
+ }
+ else if (TIMx == TIM6)
+ {
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM6, ENABLE);
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM6, DISABLE);
+ }
+ else if (TIMx == TIM7)
+ {
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM7, ENABLE);
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM7, DISABLE);
+ }
+ else if (TIMx == TIM8)
+ {
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM8, ENABLE);
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM8, DISABLE);
+ }
+ else if (TIMx == TIM9)
+ {
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM9, ENABLE);
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM9, DISABLE);
+ }
+ else if (TIMx == TIM10)
+ {
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM10, ENABLE);
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM10, DISABLE);
+ }
+ else if (TIMx == TIM11)
+ {
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM11, ENABLE);
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM11, DISABLE);
+ }
+ else if (TIMx == TIM12)
+ {
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM12, ENABLE);
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM12, DISABLE);
+ }
+ else if (TIMx == TIM13)
+ {
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM13, ENABLE);
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM13, DISABLE);
+ }
+ else if (TIMx == TIM14)
+ {
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM14, ENABLE);
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM14, DISABLE);
+ }
+ else if (TIMx == TIM15)
+ {
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM15, ENABLE);
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM15, DISABLE);
+ }
+ else if (TIMx == TIM16)
+ {
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM16, ENABLE);
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM16, DISABLE);
+ }
+ else
+ {
+ if (TIMx == TIM17)
+ {
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM17, ENABLE);
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM17, DISABLE);
+ }
+ }
+}
+
+/**
+ * @brief Initializes the TIMx Time Base Unit peripheral according to
+ * the specified parameters in the TIM_TimeBaseInitStruct.
+ * @param TIMx: where x can be 1 to 17 to select the TIM peripheral.
+ * @param TIM_TimeBaseInitStruct: pointer to a TIM_TimeBaseInitTypeDef
+ * structure that contains the configuration information for the
+ * specified TIM peripheral.
+ * @retval None
+ */
+void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct)
+{
+ uint16_t tmpcr1 = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+ assert_param(IS_TIM_COUNTER_MODE(TIM_TimeBaseInitStruct->TIM_CounterMode));
+ assert_param(IS_TIM_CKD_DIV(TIM_TimeBaseInitStruct->TIM_ClockDivision));
+
+ tmpcr1 = TIMx->CR1;
+
+ if((TIMx == TIM1) || (TIMx == TIM8)|| (TIMx == TIM2) || (TIMx == TIM3)||
+ (TIMx == TIM4) || (TIMx == TIM5))
+ {
+ /* Select the Counter Mode */
+ tmpcr1 &= (uint16_t)(~((uint16_t)(TIM_CR1_DIR | TIM_CR1_CMS)));
+ tmpcr1 |= (uint32_t)TIM_TimeBaseInitStruct->TIM_CounterMode;
+ }
+
+ if((TIMx != TIM6) && (TIMx != TIM7))
+ {
+ /* Set the clock division */
+ tmpcr1 &= (uint16_t)(~((uint16_t)TIM_CR1_CKD));
+ tmpcr1 |= (uint32_t)TIM_TimeBaseInitStruct->TIM_ClockDivision;
+ }
+
+ TIMx->CR1 = tmpcr1;
+
+ /* Set the Autoreload value */
+ TIMx->ARR = TIM_TimeBaseInitStruct->TIM_Period ;
+
+ /* Set the Prescaler value */
+ TIMx->PSC = TIM_TimeBaseInitStruct->TIM_Prescaler;
+
+ if ((TIMx == TIM1) || (TIMx == TIM8)|| (TIMx == TIM15)|| (TIMx == TIM16) || (TIMx == TIM17))
+ {
+ /* Set the Repetition Counter value */
+ TIMx->RCR = TIM_TimeBaseInitStruct->TIM_RepetitionCounter;
+ }
+
+ /* Generate an update event to reload the Prescaler and the Repetition counter
+ values immediately */
+ TIMx->EGR = TIM_PSCReloadMode_Immediate;
+}
+
+/**
+ * @brief Initializes the TIMx Channel1 according to the specified
+ * parameters in the TIM_OCInitStruct.
+ * @param TIMx: where x can be 1 to 17 except 6 and 7 to select the TIM peripheral.
+ * @param TIM_OCInitStruct: pointer to a TIM_OCInitTypeDef structure
+ * that contains the configuration information for the specified TIM peripheral.
+ * @retval None
+ */
+void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct)
+{
+ uint16_t tmpccmrx = 0, tmpccer = 0, tmpcr2 = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST8_PERIPH(TIMx));
+ assert_param(IS_TIM_OC_MODE(TIM_OCInitStruct->TIM_OCMode));
+ assert_param(IS_TIM_OUTPUT_STATE(TIM_OCInitStruct->TIM_OutputState));
+ assert_param(IS_TIM_OC_POLARITY(TIM_OCInitStruct->TIM_OCPolarity));
+ /* Disable the Channel 1: Reset the CC1E Bit */
+ TIMx->CCER &= (uint16_t)(~(uint16_t)TIM_CCER_CC1E);
+ /* Get the TIMx CCER register value */
+ tmpccer = TIMx->CCER;
+ /* Get the TIMx CR2 register value */
+ tmpcr2 = TIMx->CR2;
+
+ /* Get the TIMx CCMR1 register value */
+ tmpccmrx = TIMx->CCMR1;
+
+ /* Reset the Output Compare Mode Bits */
+ tmpccmrx &= (uint16_t)(~((uint16_t)TIM_CCMR1_OC1M));
+ tmpccmrx &= (uint16_t)(~((uint16_t)TIM_CCMR1_CC1S));
+
+ /* Select the Output Compare Mode */
+ tmpccmrx |= TIM_OCInitStruct->TIM_OCMode;
+
+ /* Reset the Output Polarity level */
+ tmpccer &= (uint16_t)(~((uint16_t)TIM_CCER_CC1P));
+ /* Set the Output Compare Polarity */
+ tmpccer |= TIM_OCInitStruct->TIM_OCPolarity;
+
+ /* Set the Output State */
+ tmpccer |= TIM_OCInitStruct->TIM_OutputState;
+
+ if((TIMx == TIM1) || (TIMx == TIM8)|| (TIMx == TIM15)||
+ (TIMx == TIM16)|| (TIMx == TIM17))
+ {
+ assert_param(IS_TIM_OUTPUTN_STATE(TIM_OCInitStruct->TIM_OutputNState));
+ assert_param(IS_TIM_OCN_POLARITY(TIM_OCInitStruct->TIM_OCNPolarity));
+ assert_param(IS_TIM_OCNIDLE_STATE(TIM_OCInitStruct->TIM_OCNIdleState));
+ assert_param(IS_TIM_OCIDLE_STATE(TIM_OCInitStruct->TIM_OCIdleState));
+
+ /* Reset the Output N Polarity level */
+ tmpccer &= (uint16_t)(~((uint16_t)TIM_CCER_CC1NP));
+ /* Set the Output N Polarity */
+ tmpccer |= TIM_OCInitStruct->TIM_OCNPolarity;
+
+ /* Reset the Output N State */
+ tmpccer &= (uint16_t)(~((uint16_t)TIM_CCER_CC1NE));
+ /* Set the Output N State */
+ tmpccer |= TIM_OCInitStruct->TIM_OutputNState;
+
+ /* Reset the Output Compare and Output Compare N IDLE State */
+ tmpcr2 &= (uint16_t)(~((uint16_t)TIM_CR2_OIS1));
+ tmpcr2 &= (uint16_t)(~((uint16_t)TIM_CR2_OIS1N));
+
+ /* Set the Output Idle state */
+ tmpcr2 |= TIM_OCInitStruct->TIM_OCIdleState;
+ /* Set the Output N Idle state */
+ tmpcr2 |= TIM_OCInitStruct->TIM_OCNIdleState;
+ }
+ /* Write to TIMx CR2 */
+ TIMx->CR2 = tmpcr2;
+
+ /* Write to TIMx CCMR1 */
+ TIMx->CCMR1 = tmpccmrx;
+
+ /* Set the Capture Compare Register value */
+ TIMx->CCR1 = TIM_OCInitStruct->TIM_Pulse;
+
+ /* Write to TIMx CCER */
+ TIMx->CCER = tmpccer;
+}
+
+/**
+ * @brief Initializes the TIMx Channel2 according to the specified
+ * parameters in the TIM_OCInitStruct.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 12 or 15 to select
+ * the TIM peripheral.
+ * @param TIM_OCInitStruct: pointer to a TIM_OCInitTypeDef structure
+ * that contains the configuration information for the specified TIM peripheral.
+ * @retval None
+ */
+void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct)
+{
+ uint16_t tmpccmrx = 0, tmpccer = 0, tmpcr2 = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST6_PERIPH(TIMx));
+ assert_param(IS_TIM_OC_MODE(TIM_OCInitStruct->TIM_OCMode));
+ assert_param(IS_TIM_OUTPUT_STATE(TIM_OCInitStruct->TIM_OutputState));
+ assert_param(IS_TIM_OC_POLARITY(TIM_OCInitStruct->TIM_OCPolarity));
+ /* Disable the Channel 2: Reset the CC2E Bit */
+ TIMx->CCER &= (uint16_t)(~((uint16_t)TIM_CCER_CC2E));
+
+ /* Get the TIMx CCER register value */
+ tmpccer = TIMx->CCER;
+ /* Get the TIMx CR2 register value */
+ tmpcr2 = TIMx->CR2;
+
+ /* Get the TIMx CCMR1 register value */
+ tmpccmrx = TIMx->CCMR1;
+
+ /* Reset the Output Compare mode and Capture/Compare selection Bits */
+ tmpccmrx &= (uint16_t)(~((uint16_t)TIM_CCMR1_OC2M));
+ tmpccmrx &= (uint16_t)(~((uint16_t)TIM_CCMR1_CC2S));
+
+ /* Select the Output Compare Mode */
+ tmpccmrx |= (uint16_t)(TIM_OCInitStruct->TIM_OCMode << 8);
+
+ /* Reset the Output Polarity level */
+ tmpccer &= (uint16_t)(~((uint16_t)TIM_CCER_CC2P));
+ /* Set the Output Compare Polarity */
+ tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OCPolarity << 4);
+
+ /* Set the Output State */
+ tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OutputState << 4);
+
+ if((TIMx == TIM1) || (TIMx == TIM8))
+ {
+ assert_param(IS_TIM_OUTPUTN_STATE(TIM_OCInitStruct->TIM_OutputNState));
+ assert_param(IS_TIM_OCN_POLARITY(TIM_OCInitStruct->TIM_OCNPolarity));
+ assert_param(IS_TIM_OCNIDLE_STATE(TIM_OCInitStruct->TIM_OCNIdleState));
+ assert_param(IS_TIM_OCIDLE_STATE(TIM_OCInitStruct->TIM_OCIdleState));
+
+ /* Reset the Output N Polarity level */
+ tmpccer &= (uint16_t)(~((uint16_t)TIM_CCER_CC2NP));
+ /* Set the Output N Polarity */
+ tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OCNPolarity << 4);
+
+ /* Reset the Output N State */
+ tmpccer &= (uint16_t)(~((uint16_t)TIM_CCER_CC2NE));
+ /* Set the Output N State */
+ tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OutputNState << 4);
+
+ /* Reset the Output Compare and Output Compare N IDLE State */
+ tmpcr2 &= (uint16_t)(~((uint16_t)TIM_CR2_OIS2));
+ tmpcr2 &= (uint16_t)(~((uint16_t)TIM_CR2_OIS2N));
+
+ /* Set the Output Idle state */
+ tmpcr2 |= (uint16_t)(TIM_OCInitStruct->TIM_OCIdleState << 2);
+ /* Set the Output N Idle state */
+ tmpcr2 |= (uint16_t)(TIM_OCInitStruct->TIM_OCNIdleState << 2);
+ }
+ /* Write to TIMx CR2 */
+ TIMx->CR2 = tmpcr2;
+
+ /* Write to TIMx CCMR1 */
+ TIMx->CCMR1 = tmpccmrx;
+
+ /* Set the Capture Compare Register value */
+ TIMx->CCR2 = TIM_OCInitStruct->TIM_Pulse;
+
+ /* Write to TIMx CCER */
+ TIMx->CCER = tmpccer;
+}
+
+/**
+ * @brief Initializes the TIMx Channel3 according to the specified
+ * parameters in the TIM_OCInitStruct.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+ * @param TIM_OCInitStruct: pointer to a TIM_OCInitTypeDef structure
+ * that contains the configuration information for the specified TIM peripheral.
+ * @retval None
+ */
+void TIM_OC3Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct)
+{
+ uint16_t tmpccmrx = 0, tmpccer = 0, tmpcr2 = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_TIM_OC_MODE(TIM_OCInitStruct->TIM_OCMode));
+ assert_param(IS_TIM_OUTPUT_STATE(TIM_OCInitStruct->TIM_OutputState));
+ assert_param(IS_TIM_OC_POLARITY(TIM_OCInitStruct->TIM_OCPolarity));
+ /* Disable the Channel 2: Reset the CC2E Bit */
+ TIMx->CCER &= (uint16_t)(~((uint16_t)TIM_CCER_CC3E));
+
+ /* Get the TIMx CCER register value */
+ tmpccer = TIMx->CCER;
+ /* Get the TIMx CR2 register value */
+ tmpcr2 = TIMx->CR2;
+
+ /* Get the TIMx CCMR2 register value */
+ tmpccmrx = TIMx->CCMR2;
+
+ /* Reset the Output Compare mode and Capture/Compare selection Bits */
+ tmpccmrx &= (uint16_t)(~((uint16_t)TIM_CCMR2_OC3M));
+ tmpccmrx &= (uint16_t)(~((uint16_t)TIM_CCMR2_CC3S));
+ /* Select the Output Compare Mode */
+ tmpccmrx |= TIM_OCInitStruct->TIM_OCMode;
+
+ /* Reset the Output Polarity level */
+ tmpccer &= (uint16_t)(~((uint16_t)TIM_CCER_CC3P));
+ /* Set the Output Compare Polarity */
+ tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OCPolarity << 8);
+
+ /* Set the Output State */
+ tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OutputState << 8);
+
+ if((TIMx == TIM1) || (TIMx == TIM8))
+ {
+ assert_param(IS_TIM_OUTPUTN_STATE(TIM_OCInitStruct->TIM_OutputNState));
+ assert_param(IS_TIM_OCN_POLARITY(TIM_OCInitStruct->TIM_OCNPolarity));
+ assert_param(IS_TIM_OCNIDLE_STATE(TIM_OCInitStruct->TIM_OCNIdleState));
+ assert_param(IS_TIM_OCIDLE_STATE(TIM_OCInitStruct->TIM_OCIdleState));
+
+ /* Reset the Output N Polarity level */
+ tmpccer &= (uint16_t)(~((uint16_t)TIM_CCER_CC3NP));
+ /* Set the Output N Polarity */
+ tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OCNPolarity << 8);
+ /* Reset the Output N State */
+ tmpccer &= (uint16_t)(~((uint16_t)TIM_CCER_CC3NE));
+
+ /* Set the Output N State */
+ tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OutputNState << 8);
+ /* Reset the Output Compare and Output Compare N IDLE State */
+ tmpcr2 &= (uint16_t)(~((uint16_t)TIM_CR2_OIS3));
+ tmpcr2 &= (uint16_t)(~((uint16_t)TIM_CR2_OIS3N));
+ /* Set the Output Idle state */
+ tmpcr2 |= (uint16_t)(TIM_OCInitStruct->TIM_OCIdleState << 4);
+ /* Set the Output N Idle state */
+ tmpcr2 |= (uint16_t)(TIM_OCInitStruct->TIM_OCNIdleState << 4);
+ }
+ /* Write to TIMx CR2 */
+ TIMx->CR2 = tmpcr2;
+
+ /* Write to TIMx CCMR2 */
+ TIMx->CCMR2 = tmpccmrx;
+
+ /* Set the Capture Compare Register value */
+ TIMx->CCR3 = TIM_OCInitStruct->TIM_Pulse;
+
+ /* Write to TIMx CCER */
+ TIMx->CCER = tmpccer;
+}
+
+/**
+ * @brief Initializes the TIMx Channel4 according to the specified
+ * parameters in the TIM_OCInitStruct.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+ * @param TIM_OCInitStruct: pointer to a TIM_OCInitTypeDef structure
+ * that contains the configuration information for the specified TIM peripheral.
+ * @retval None
+ */
+void TIM_OC4Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct)
+{
+ uint16_t tmpccmrx = 0, tmpccer = 0, tmpcr2 = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_TIM_OC_MODE(TIM_OCInitStruct->TIM_OCMode));
+ assert_param(IS_TIM_OUTPUT_STATE(TIM_OCInitStruct->TIM_OutputState));
+ assert_param(IS_TIM_OC_POLARITY(TIM_OCInitStruct->TIM_OCPolarity));
+ /* Disable the Channel 2: Reset the CC4E Bit */
+ TIMx->CCER &= (uint16_t)(~((uint16_t)TIM_CCER_CC4E));
+
+ /* Get the TIMx CCER register value */
+ tmpccer = TIMx->CCER;
+ /* Get the TIMx CR2 register value */
+ tmpcr2 = TIMx->CR2;
+
+ /* Get the TIMx CCMR2 register value */
+ tmpccmrx = TIMx->CCMR2;
+
+ /* Reset the Output Compare mode and Capture/Compare selection Bits */
+ tmpccmrx &= (uint16_t)(~((uint16_t)TIM_CCMR2_OC4M));
+ tmpccmrx &= (uint16_t)(~((uint16_t)TIM_CCMR2_CC4S));
+
+ /* Select the Output Compare Mode */
+ tmpccmrx |= (uint16_t)(TIM_OCInitStruct->TIM_OCMode << 8);
+
+ /* Reset the Output Polarity level */
+ tmpccer &= (uint16_t)(~((uint16_t)TIM_CCER_CC4P));
+ /* Set the Output Compare Polarity */
+ tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OCPolarity << 12);
+
+ /* Set the Output State */
+ tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OutputState << 12);
+
+ if((TIMx == TIM1) || (TIMx == TIM8))
+ {
+ assert_param(IS_TIM_OCIDLE_STATE(TIM_OCInitStruct->TIM_OCIdleState));
+ /* Reset the Output Compare IDLE State */
+ tmpcr2 &= (uint16_t)(~((uint16_t)TIM_CR2_OIS4));
+ /* Set the Output Idle state */
+ tmpcr2 |= (uint16_t)(TIM_OCInitStruct->TIM_OCIdleState << 6);
+ }
+ /* Write to TIMx CR2 */
+ TIMx->CR2 = tmpcr2;
+
+ /* Write to TIMx CCMR2 */
+ TIMx->CCMR2 = tmpccmrx;
+
+ /* Set the Capture Compare Register value */
+ TIMx->CCR4 = TIM_OCInitStruct->TIM_Pulse;
+
+ /* Write to TIMx CCER */
+ TIMx->CCER = tmpccer;
+}
+
+/**
+ * @brief Initializes the TIM peripheral according to the specified
+ * parameters in the TIM_ICInitStruct.
+ * @param TIMx: where x can be 1 to 17 except 6 and 7 to select the TIM peripheral.
+ * @param TIM_ICInitStruct: pointer to a TIM_ICInitTypeDef structure
+ * that contains the configuration information for the specified TIM peripheral.
+ * @retval None
+ */
+void TIM_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_CHANNEL(TIM_ICInitStruct->TIM_Channel));
+ assert_param(IS_TIM_IC_SELECTION(TIM_ICInitStruct->TIM_ICSelection));
+ assert_param(IS_TIM_IC_PRESCALER(TIM_ICInitStruct->TIM_ICPrescaler));
+ assert_param(IS_TIM_IC_FILTER(TIM_ICInitStruct->TIM_ICFilter));
+
+ if((TIMx == TIM1) || (TIMx == TIM8) || (TIMx == TIM2) || (TIMx == TIM3) ||
+ (TIMx == TIM4) ||(TIMx == TIM5))
+ {
+ assert_param(IS_TIM_IC_POLARITY(TIM_ICInitStruct->TIM_ICPolarity));
+ }
+ else
+ {
+ assert_param(IS_TIM_IC_POLARITY_LITE(TIM_ICInitStruct->TIM_ICPolarity));
+ }
+ if (TIM_ICInitStruct->TIM_Channel == TIM_Channel_1)
+ {
+ assert_param(IS_TIM_LIST8_PERIPH(TIMx));
+ /* TI1 Configuration */
+ TI1_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity,
+ TIM_ICInitStruct->TIM_ICSelection,
+ TIM_ICInitStruct->TIM_ICFilter);
+ /* Set the Input Capture Prescaler value */
+ TIM_SetIC1Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler);
+ }
+ else if (TIM_ICInitStruct->TIM_Channel == TIM_Channel_2)
+ {
+ assert_param(IS_TIM_LIST6_PERIPH(TIMx));
+ /* TI2 Configuration */
+ TI2_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity,
+ TIM_ICInitStruct->TIM_ICSelection,
+ TIM_ICInitStruct->TIM_ICFilter);
+ /* Set the Input Capture Prescaler value */
+ TIM_SetIC2Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler);
+ }
+ else if (TIM_ICInitStruct->TIM_Channel == TIM_Channel_3)
+ {
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ /* TI3 Configuration */
+ TI3_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity,
+ TIM_ICInitStruct->TIM_ICSelection,
+ TIM_ICInitStruct->TIM_ICFilter);
+ /* Set the Input Capture Prescaler value */
+ TIM_SetIC3Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler);
+ }
+ else
+ {
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ /* TI4 Configuration */
+ TI4_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity,
+ TIM_ICInitStruct->TIM_ICSelection,
+ TIM_ICInitStruct->TIM_ICFilter);
+ /* Set the Input Capture Prescaler value */
+ TIM_SetIC4Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler);
+ }
+}
+
+/**
+ * @brief Configures the TIM peripheral according to the specified
+ * parameters in the TIM_ICInitStruct to measure an external PWM signal.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 12 or 15 to select the TIM peripheral.
+ * @param TIM_ICInitStruct: pointer to a TIM_ICInitTypeDef structure
+ * that contains the configuration information for the specified TIM peripheral.
+ * @retval None
+ */
+void TIM_PWMIConfig(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct)
+{
+ uint16_t icoppositepolarity = TIM_ICPolarity_Rising;
+ uint16_t icoppositeselection = TIM_ICSelection_DirectTI;
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST6_PERIPH(TIMx));
+ /* Select the Opposite Input Polarity */
+ if (TIM_ICInitStruct->TIM_ICPolarity == TIM_ICPolarity_Rising)
+ {
+ icoppositepolarity = TIM_ICPolarity_Falling;
+ }
+ else
+ {
+ icoppositepolarity = TIM_ICPolarity_Rising;
+ }
+ /* Select the Opposite Input */
+ if (TIM_ICInitStruct->TIM_ICSelection == TIM_ICSelection_DirectTI)
+ {
+ icoppositeselection = TIM_ICSelection_IndirectTI;
+ }
+ else
+ {
+ icoppositeselection = TIM_ICSelection_DirectTI;
+ }
+ if (TIM_ICInitStruct->TIM_Channel == TIM_Channel_1)
+ {
+ /* TI1 Configuration */
+ TI1_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity, TIM_ICInitStruct->TIM_ICSelection,
+ TIM_ICInitStruct->TIM_ICFilter);
+ /* Set the Input Capture Prescaler value */
+ TIM_SetIC1Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler);
+ /* TI2 Configuration */
+ TI2_Config(TIMx, icoppositepolarity, icoppositeselection, TIM_ICInitStruct->TIM_ICFilter);
+ /* Set the Input Capture Prescaler value */
+ TIM_SetIC2Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler);
+ }
+ else
+ {
+ /* TI2 Configuration */
+ TI2_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity, TIM_ICInitStruct->TIM_ICSelection,
+ TIM_ICInitStruct->TIM_ICFilter);
+ /* Set the Input Capture Prescaler value */
+ TIM_SetIC2Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler);
+ /* TI1 Configuration */
+ TI1_Config(TIMx, icoppositepolarity, icoppositeselection, TIM_ICInitStruct->TIM_ICFilter);
+ /* Set the Input Capture Prescaler value */
+ TIM_SetIC1Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler);
+ }
+}
+
+/**
+ * @brief Configures the: Break feature, dead time, Lock level, the OSSI,
+ * the OSSR State and the AOE(automatic output enable).
+ * @param TIMx: where x can be 1 or 8 to select the TIM
+ * @param TIM_BDTRInitStruct: pointer to a TIM_BDTRInitTypeDef structure that
+ * contains the BDTR Register configuration information for the TIM peripheral.
+ * @retval None
+ */
+void TIM_BDTRConfig(TIM_TypeDef* TIMx, TIM_BDTRInitTypeDef *TIM_BDTRInitStruct)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST2_PERIPH(TIMx));
+ assert_param(IS_TIM_OSSR_STATE(TIM_BDTRInitStruct->TIM_OSSRState));
+ assert_param(IS_TIM_OSSI_STATE(TIM_BDTRInitStruct->TIM_OSSIState));
+ assert_param(IS_TIM_LOCK_LEVEL(TIM_BDTRInitStruct->TIM_LOCKLevel));
+ assert_param(IS_TIM_BREAK_STATE(TIM_BDTRInitStruct->TIM_Break));
+ assert_param(IS_TIM_BREAK_POLARITY(TIM_BDTRInitStruct->TIM_BreakPolarity));
+ assert_param(IS_TIM_AUTOMATIC_OUTPUT_STATE(TIM_BDTRInitStruct->TIM_AutomaticOutput));
+ /* Set the Lock level, the Break enable Bit and the Ploarity, the OSSR State,
+ the OSSI State, the dead time value and the Automatic Output Enable Bit */
+ TIMx->BDTR = (uint32_t)TIM_BDTRInitStruct->TIM_OSSRState | TIM_BDTRInitStruct->TIM_OSSIState |
+ TIM_BDTRInitStruct->TIM_LOCKLevel | TIM_BDTRInitStruct->TIM_DeadTime |
+ TIM_BDTRInitStruct->TIM_Break | TIM_BDTRInitStruct->TIM_BreakPolarity |
+ TIM_BDTRInitStruct->TIM_AutomaticOutput;
+}
+
+/**
+ * @brief Fills each TIM_TimeBaseInitStruct member with its default value.
+ * @param TIM_TimeBaseInitStruct : pointer to a TIM_TimeBaseInitTypeDef
+ * structure which will be initialized.
+ * @retval None
+ */
+void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct)
+{
+ /* Set the default configuration */
+ TIM_TimeBaseInitStruct->TIM_Period = 0xFFFF;
+ TIM_TimeBaseInitStruct->TIM_Prescaler = 0x0000;
+ TIM_TimeBaseInitStruct->TIM_ClockDivision = TIM_CKD_DIV1;
+ TIM_TimeBaseInitStruct->TIM_CounterMode = TIM_CounterMode_Up;
+ TIM_TimeBaseInitStruct->TIM_RepetitionCounter = 0x0000;
+}
+
+/**
+ * @brief Fills each TIM_OCInitStruct member with its default value.
+ * @param TIM_OCInitStruct : pointer to a TIM_OCInitTypeDef structure which will
+ * be initialized.
+ * @retval None
+ */
+void TIM_OCStructInit(TIM_OCInitTypeDef* TIM_OCInitStruct)
+{
+ /* Set the default configuration */
+ TIM_OCInitStruct->TIM_OCMode = TIM_OCMode_Timing;
+ TIM_OCInitStruct->TIM_OutputState = TIM_OutputState_Disable;
+ TIM_OCInitStruct->TIM_OutputNState = TIM_OutputNState_Disable;
+ TIM_OCInitStruct->TIM_Pulse = 0x0000;
+ TIM_OCInitStruct->TIM_OCPolarity = TIM_OCPolarity_High;
+ TIM_OCInitStruct->TIM_OCNPolarity = TIM_OCPolarity_High;
+ TIM_OCInitStruct->TIM_OCIdleState = TIM_OCIdleState_Reset;
+ TIM_OCInitStruct->TIM_OCNIdleState = TIM_OCNIdleState_Reset;
+}
+
+/**
+ * @brief Fills each TIM_ICInitStruct member with its default value.
+ * @param TIM_ICInitStruct: pointer to a TIM_ICInitTypeDef structure which will
+ * be initialized.
+ * @retval None
+ */
+void TIM_ICStructInit(TIM_ICInitTypeDef* TIM_ICInitStruct)
+{
+ /* Set the default configuration */
+ TIM_ICInitStruct->TIM_Channel = TIM_Channel_1;
+ TIM_ICInitStruct->TIM_ICPolarity = TIM_ICPolarity_Rising;
+ TIM_ICInitStruct->TIM_ICSelection = TIM_ICSelection_DirectTI;
+ TIM_ICInitStruct->TIM_ICPrescaler = TIM_ICPSC_DIV1;
+ TIM_ICInitStruct->TIM_ICFilter = 0x00;
+}
+
+/**
+ * @brief Fills each TIM_BDTRInitStruct member with its default value.
+ * @param TIM_BDTRInitStruct: pointer to a TIM_BDTRInitTypeDef structure which
+ * will be initialized.
+ * @retval None
+ */
+void TIM_BDTRStructInit(TIM_BDTRInitTypeDef* TIM_BDTRInitStruct)
+{
+ /* Set the default configuration */
+ TIM_BDTRInitStruct->TIM_OSSRState = TIM_OSSRState_Disable;
+ TIM_BDTRInitStruct->TIM_OSSIState = TIM_OSSIState_Disable;
+ TIM_BDTRInitStruct->TIM_LOCKLevel = TIM_LOCKLevel_OFF;
+ TIM_BDTRInitStruct->TIM_DeadTime = 0x00;
+ TIM_BDTRInitStruct->TIM_Break = TIM_Break_Disable;
+ TIM_BDTRInitStruct->TIM_BreakPolarity = TIM_BreakPolarity_Low;
+ TIM_BDTRInitStruct->TIM_AutomaticOutput = TIM_AutomaticOutput_Disable;
+}
+
+/**
+ * @brief Enables or disables the specified TIM peripheral.
+ * @param TIMx: where x can be 1 to 17 to select the TIMx peripheral.
+ * @param NewState: new state of the TIMx peripheral.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the TIM Counter */
+ TIMx->CR1 |= TIM_CR1_CEN;
+ }
+ else
+ {
+ /* Disable the TIM Counter */
+ TIMx->CR1 &= (uint16_t)(~((uint16_t)TIM_CR1_CEN));
+ }
+}
+
+/**
+ * @brief Enables or disables the TIM peripheral Main Outputs.
+ * @param TIMx: where x can be 1, 8, 15, 16 or 17 to select the TIMx peripheral.
+ * @param NewState: new state of the TIM peripheral Main Outputs.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void TIM_CtrlPWMOutputs(TIM_TypeDef* TIMx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST2_PERIPH(TIMx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Enable the TIM Main Output */
+ TIMx->BDTR |= TIM_BDTR_MOE;
+ }
+ else
+ {
+ /* Disable the TIM Main Output */
+ TIMx->BDTR &= (uint16_t)(~((uint16_t)TIM_BDTR_MOE));
+ }
+}
+
+/**
+ * @brief Enables or disables the specified TIM interrupts.
+ * @param TIMx: where x can be 1 to 17 to select the TIMx peripheral.
+ * @param TIM_IT: specifies the TIM interrupts sources to be enabled or disabled.
+ * This parameter can be any combination of the following values:
+ * @arg TIM_IT_Update: TIM update Interrupt source
+ * @arg TIM_IT_CC1: TIM Capture Compare 1 Interrupt source
+ * @arg TIM_IT_CC2: TIM Capture Compare 2 Interrupt source
+ * @arg TIM_IT_CC3: TIM Capture Compare 3 Interrupt source
+ * @arg TIM_IT_CC4: TIM Capture Compare 4 Interrupt source
+ * @arg TIM_IT_COM: TIM Commutation Interrupt source
+ * @arg TIM_IT_Trigger: TIM Trigger Interrupt source
+ * @arg TIM_IT_Break: TIM Break Interrupt source
+ * @note
+ * - TIM6 and TIM7 can only generate an update interrupt.
+ * - TIM9, TIM12 and TIM15 can have only TIM_IT_Update, TIM_IT_CC1,
+ * TIM_IT_CC2 or TIM_IT_Trigger.
+ * - TIM10, TIM11, TIM13, TIM14, TIM16 and TIM17 can have TIM_IT_Update or TIM_IT_CC1.
+ * - TIM_IT_Break is used only with TIM1, TIM8 and TIM15.
+ * - TIM_IT_COM is used only with TIM1, TIM8, TIM15, TIM16 and TIM17.
+ * @param NewState: new state of the TIM interrupts.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+ assert_param(IS_TIM_IT(TIM_IT));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the Interrupt sources */
+ TIMx->DIER |= TIM_IT;
+ }
+ else
+ {
+ /* Disable the Interrupt sources */
+ TIMx->DIER &= (uint16_t)~TIM_IT;
+ }
+}
+
+/**
+ * @brief Configures the TIMx event to be generate by software.
+ * @param TIMx: where x can be 1 to 17 to select the TIM peripheral.
+ * @param TIM_EventSource: specifies the event source.
+ * This parameter can be one or more of the following values:
+ * @arg TIM_EventSource_Update: Timer update Event source
+ * @arg TIM_EventSource_CC1: Timer Capture Compare 1 Event source
+ * @arg TIM_EventSource_CC2: Timer Capture Compare 2 Event source
+ * @arg TIM_EventSource_CC3: Timer Capture Compare 3 Event source
+ * @arg TIM_EventSource_CC4: Timer Capture Compare 4 Event source
+ * @arg TIM_EventSource_COM: Timer COM event source
+ * @arg TIM_EventSource_Trigger: Timer Trigger Event source
+ * @arg TIM_EventSource_Break: Timer Break event source
+ * @note
+ * - TIM6 and TIM7 can only generate an update event.
+ * - TIM_EventSource_COM and TIM_EventSource_Break are used only with TIM1 and TIM8.
+ * @retval None
+ */
+void TIM_GenerateEvent(TIM_TypeDef* TIMx, uint16_t TIM_EventSource)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+ assert_param(IS_TIM_EVENT_SOURCE(TIM_EventSource));
+
+ /* Set the event sources */
+ TIMx->EGR = TIM_EventSource;
+}
+
+/**
+ * @brief Configures the TIMx's DMA interface.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 15, 16 or 17 to select
+ * the TIM peripheral.
+ * @param TIM_DMABase: DMA Base address.
+ * This parameter can be one of the following values:
+ * @arg TIM_DMABase_CR, TIM_DMABase_CR2, TIM_DMABase_SMCR,
+ * TIM_DMABase_DIER, TIM1_DMABase_SR, TIM_DMABase_EGR,
+ * TIM_DMABase_CCMR1, TIM_DMABase_CCMR2, TIM_DMABase_CCER,
+ * TIM_DMABase_CNT, TIM_DMABase_PSC, TIM_DMABase_ARR,
+ * TIM_DMABase_RCR, TIM_DMABase_CCR1, TIM_DMABase_CCR2,
+ * TIM_DMABase_CCR3, TIM_DMABase_CCR4, TIM_DMABase_BDTR,
+ * TIM_DMABase_DCR.
+ * @param TIM_DMABurstLength: DMA Burst length.
+ * This parameter can be one value between:
+ * TIM_DMABurstLength_1Transfer and TIM_DMABurstLength_18Transfers.
+ * @retval None
+ */
+void TIM_DMAConfig(TIM_TypeDef* TIMx, uint16_t TIM_DMABase, uint16_t TIM_DMABurstLength)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST4_PERIPH(TIMx));
+ assert_param(IS_TIM_DMA_BASE(TIM_DMABase));
+ assert_param(IS_TIM_DMA_LENGTH(TIM_DMABurstLength));
+ /* Set the DMA Base and the DMA Burst Length */
+ TIMx->DCR = TIM_DMABase | TIM_DMABurstLength;
+}
+
+/**
+ * @brief Enables or disables the TIMx's DMA Requests.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5, 6, 7, 8, 15, 16 or 17
+ * to select the TIM peripheral.
+ * @param TIM_DMASource: specifies the DMA Request sources.
+ * This parameter can be any combination of the following values:
+ * @arg TIM_DMA_Update: TIM update Interrupt source
+ * @arg TIM_DMA_CC1: TIM Capture Compare 1 DMA source
+ * @arg TIM_DMA_CC2: TIM Capture Compare 2 DMA source
+ * @arg TIM_DMA_CC3: TIM Capture Compare 3 DMA source
+ * @arg TIM_DMA_CC4: TIM Capture Compare 4 DMA source
+ * @arg TIM_DMA_COM: TIM Commutation DMA source
+ * @arg TIM_DMA_Trigger: TIM Trigger DMA source
+ * @param NewState: new state of the DMA Request sources.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void TIM_DMACmd(TIM_TypeDef* TIMx, uint16_t TIM_DMASource, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST9_PERIPH(TIMx));
+ assert_param(IS_TIM_DMA_SOURCE(TIM_DMASource));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the DMA sources */
+ TIMx->DIER |= TIM_DMASource;
+ }
+ else
+ {
+ /* Disable the DMA sources */
+ TIMx->DIER &= (uint16_t)~TIM_DMASource;
+ }
+}
+
+/**
+ * @brief Configures the TIMx internal Clock
+ * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 12 or 15
+ * to select the TIM peripheral.
+ * @retval None
+ */
+void TIM_InternalClockConfig(TIM_TypeDef* TIMx)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST6_PERIPH(TIMx));
+ /* Disable slave mode to clock the prescaler directly with the internal clock */
+ TIMx->SMCR &= (uint16_t)(~((uint16_t)TIM_SMCR_SMS));
+}
+
+/**
+ * @brief Configures the TIMx Internal Trigger as External Clock
+ * @param TIMx: where x can be 1, 2, 3, 4, 5, 9, 12 or 15 to select the TIM peripheral.
+ * @param TIM_ITRSource: Trigger source.
+ * This parameter can be one of the following values:
+ * @param TIM_TS_ITR0: Internal Trigger 0
+ * @param TIM_TS_ITR1: Internal Trigger 1
+ * @param TIM_TS_ITR2: Internal Trigger 2
+ * @param TIM_TS_ITR3: Internal Trigger 3
+ * @retval None
+ */
+void TIM_ITRxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST6_PERIPH(TIMx));
+ assert_param(IS_TIM_INTERNAL_TRIGGER_SELECTION(TIM_InputTriggerSource));
+ /* Select the Internal Trigger */
+ TIM_SelectInputTrigger(TIMx, TIM_InputTriggerSource);
+ /* Select the External clock mode1 */
+ TIMx->SMCR |= TIM_SlaveMode_External1;
+}
+
+/**
+ * @brief Configures the TIMx Trigger as External Clock
+ * @param TIMx: where x can be 1, 2, 3, 4, 5, 9, 12 or 15 to select the TIM peripheral.
+ * @param TIM_TIxExternalCLKSource: Trigger source.
+ * This parameter can be one of the following values:
+ * @arg TIM_TIxExternalCLK1Source_TI1ED: TI1 Edge Detector
+ * @arg TIM_TIxExternalCLK1Source_TI1: Filtered Timer Input 1
+ * @arg TIM_TIxExternalCLK1Source_TI2: Filtered Timer Input 2
+ * @param TIM_ICPolarity: specifies the TIx Polarity.
+ * This parameter can be one of the following values:
+ * @arg TIM_ICPolarity_Rising
+ * @arg TIM_ICPolarity_Falling
+ * @param ICFilter : specifies the filter value.
+ * This parameter must be a value between 0x0 and 0xF.
+ * @retval None
+ */
+void TIM_TIxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_TIxExternalCLKSource,
+ uint16_t TIM_ICPolarity, uint16_t ICFilter)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST6_PERIPH(TIMx));
+ assert_param(IS_TIM_TIXCLK_SOURCE(TIM_TIxExternalCLKSource));
+ assert_param(IS_TIM_IC_POLARITY(TIM_ICPolarity));
+ assert_param(IS_TIM_IC_FILTER(ICFilter));
+ /* Configure the Timer Input Clock Source */
+ if (TIM_TIxExternalCLKSource == TIM_TIxExternalCLK1Source_TI2)
+ {
+ TI2_Config(TIMx, TIM_ICPolarity, TIM_ICSelection_DirectTI, ICFilter);
+ }
+ else
+ {
+ TI1_Config(TIMx, TIM_ICPolarity, TIM_ICSelection_DirectTI, ICFilter);
+ }
+ /* Select the Trigger source */
+ TIM_SelectInputTrigger(TIMx, TIM_TIxExternalCLKSource);
+ /* Select the External clock mode1 */
+ TIMx->SMCR |= TIM_SlaveMode_External1;
+}
+
+/**
+ * @brief Configures the External clock Mode1
+ * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+ * @param TIM_ExtTRGPrescaler: The external Trigger Prescaler.
+ * This parameter can be one of the following values:
+ * @arg TIM_ExtTRGPSC_OFF: ETRP Prescaler OFF.
+ * @arg TIM_ExtTRGPSC_DIV2: ETRP frequency divided by 2.
+ * @arg TIM_ExtTRGPSC_DIV4: ETRP frequency divided by 4.
+ * @arg TIM_ExtTRGPSC_DIV8: ETRP frequency divided by 8.
+ * @param TIM_ExtTRGPolarity: The external Trigger Polarity.
+ * This parameter can be one of the following values:
+ * @arg TIM_ExtTRGPolarity_Inverted: active low or falling edge active.
+ * @arg TIM_ExtTRGPolarity_NonInverted: active high or rising edge active.
+ * @param ExtTRGFilter: External Trigger Filter.
+ * This parameter must be a value between 0x00 and 0x0F
+ * @retval None
+ */
+void TIM_ETRClockMode1Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity,
+ uint16_t ExtTRGFilter)
+{
+ uint16_t tmpsmcr = 0;
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_TIM_EXT_PRESCALER(TIM_ExtTRGPrescaler));
+ assert_param(IS_TIM_EXT_POLARITY(TIM_ExtTRGPolarity));
+ assert_param(IS_TIM_EXT_FILTER(ExtTRGFilter));
+ /* Configure the ETR Clock source */
+ TIM_ETRConfig(TIMx, TIM_ExtTRGPrescaler, TIM_ExtTRGPolarity, ExtTRGFilter);
+
+ /* Get the TIMx SMCR register value */
+ tmpsmcr = TIMx->SMCR;
+ /* Reset the SMS Bits */
+ tmpsmcr &= (uint16_t)(~((uint16_t)TIM_SMCR_SMS));
+ /* Select the External clock mode1 */
+ tmpsmcr |= TIM_SlaveMode_External1;
+ /* Select the Trigger selection : ETRF */
+ tmpsmcr &= (uint16_t)(~((uint16_t)TIM_SMCR_TS));
+ tmpsmcr |= TIM_TS_ETRF;
+ /* Write to TIMx SMCR */
+ TIMx->SMCR = tmpsmcr;
+}
+
+/**
+ * @brief Configures the External clock Mode2
+ * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+ * @param TIM_ExtTRGPrescaler: The external Trigger Prescaler.
+ * This parameter can be one of the following values:
+ * @arg TIM_ExtTRGPSC_OFF: ETRP Prescaler OFF.
+ * @arg TIM_ExtTRGPSC_DIV2: ETRP frequency divided by 2.
+ * @arg TIM_ExtTRGPSC_DIV4: ETRP frequency divided by 4.
+ * @arg TIM_ExtTRGPSC_DIV8: ETRP frequency divided by 8.
+ * @param TIM_ExtTRGPolarity: The external Trigger Polarity.
+ * This parameter can be one of the following values:
+ * @arg TIM_ExtTRGPolarity_Inverted: active low or falling edge active.
+ * @arg TIM_ExtTRGPolarity_NonInverted: active high or rising edge active.
+ * @param ExtTRGFilter: External Trigger Filter.
+ * This parameter must be a value between 0x00 and 0x0F
+ * @retval None
+ */
+void TIM_ETRClockMode2Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler,
+ uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_TIM_EXT_PRESCALER(TIM_ExtTRGPrescaler));
+ assert_param(IS_TIM_EXT_POLARITY(TIM_ExtTRGPolarity));
+ assert_param(IS_TIM_EXT_FILTER(ExtTRGFilter));
+ /* Configure the ETR Clock source */
+ TIM_ETRConfig(TIMx, TIM_ExtTRGPrescaler, TIM_ExtTRGPolarity, ExtTRGFilter);
+ /* Enable the External clock mode2 */
+ TIMx->SMCR |= TIM_SMCR_ECE;
+}
+
+/**
+ * @brief Configures the TIMx External Trigger (ETR).
+ * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+ * @param TIM_ExtTRGPrescaler: The external Trigger Prescaler.
+ * This parameter can be one of the following values:
+ * @arg TIM_ExtTRGPSC_OFF: ETRP Prescaler OFF.
+ * @arg TIM_ExtTRGPSC_DIV2: ETRP frequency divided by 2.
+ * @arg TIM_ExtTRGPSC_DIV4: ETRP frequency divided by 4.
+ * @arg TIM_ExtTRGPSC_DIV8: ETRP frequency divided by 8.
+ * @param TIM_ExtTRGPolarity: The external Trigger Polarity.
+ * This parameter can be one of the following values:
+ * @arg TIM_ExtTRGPolarity_Inverted: active low or falling edge active.
+ * @arg TIM_ExtTRGPolarity_NonInverted: active high or rising edge active.
+ * @param ExtTRGFilter: External Trigger Filter.
+ * This parameter must be a value between 0x00 and 0x0F
+ * @retval None
+ */
+void TIM_ETRConfig(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity,
+ uint16_t ExtTRGFilter)
+{
+ uint16_t tmpsmcr = 0;
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_TIM_EXT_PRESCALER(TIM_ExtTRGPrescaler));
+ assert_param(IS_TIM_EXT_POLARITY(TIM_ExtTRGPolarity));
+ assert_param(IS_TIM_EXT_FILTER(ExtTRGFilter));
+ tmpsmcr = TIMx->SMCR;
+ /* Reset the ETR Bits */
+ tmpsmcr &= SMCR_ETR_Mask;
+ /* Set the Prescaler, the Filter value and the Polarity */
+ tmpsmcr |= (uint16_t)(TIM_ExtTRGPrescaler | (uint16_t)(TIM_ExtTRGPolarity | (uint16_t)(ExtTRGFilter << (uint16_t)8)));
+ /* Write to TIMx SMCR */
+ TIMx->SMCR = tmpsmcr;
+}
+
+/**
+ * @brief Configures the TIMx Prescaler.
+ * @param TIMx: where x can be 1 to 17 to select the TIM peripheral.
+ * @param Prescaler: specifies the Prescaler Register value
+ * @param TIM_PSCReloadMode: specifies the TIM Prescaler Reload mode
+ * This parameter can be one of the following values:
+ * @arg TIM_PSCReloadMode_Update: The Prescaler is loaded at the update event.
+ * @arg TIM_PSCReloadMode_Immediate: The Prescaler is loaded immediately.
+ * @retval None
+ */
+void TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler, uint16_t TIM_PSCReloadMode)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+ assert_param(IS_TIM_PRESCALER_RELOAD(TIM_PSCReloadMode));
+ /* Set the Prescaler value */
+ TIMx->PSC = Prescaler;
+ /* Set or reset the UG Bit */
+ TIMx->EGR = TIM_PSCReloadMode;
+}
+
+/**
+ * @brief Specifies the TIMx Counter Mode to be used.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+ * @param TIM_CounterMode: specifies the Counter Mode to be used
+ * This parameter can be one of the following values:
+ * @arg TIM_CounterMode_Up: TIM Up Counting Mode
+ * @arg TIM_CounterMode_Down: TIM Down Counting Mode
+ * @arg TIM_CounterMode_CenterAligned1: TIM Center Aligned Mode1
+ * @arg TIM_CounterMode_CenterAligned2: TIM Center Aligned Mode2
+ * @arg TIM_CounterMode_CenterAligned3: TIM Center Aligned Mode3
+ * @retval None
+ */
+void TIM_CounterModeConfig(TIM_TypeDef* TIMx, uint16_t TIM_CounterMode)
+{
+ uint16_t tmpcr1 = 0;
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_TIM_COUNTER_MODE(TIM_CounterMode));
+ tmpcr1 = TIMx->CR1;
+ /* Reset the CMS and DIR Bits */
+ tmpcr1 &= (uint16_t)(~((uint16_t)(TIM_CR1_DIR | TIM_CR1_CMS)));
+ /* Set the Counter Mode */
+ tmpcr1 |= TIM_CounterMode;
+ /* Write to TIMx CR1 register */
+ TIMx->CR1 = tmpcr1;
+}
+
+/**
+ * @brief Selects the Input Trigger source
+ * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 12 or 15 to select the TIM peripheral.
+ * @param TIM_InputTriggerSource: The Input Trigger source.
+ * This parameter can be one of the following values:
+ * @arg TIM_TS_ITR0: Internal Trigger 0
+ * @arg TIM_TS_ITR1: Internal Trigger 1
+ * @arg TIM_TS_ITR2: Internal Trigger 2
+ * @arg TIM_TS_ITR3: Internal Trigger 3
+ * @arg TIM_TS_TI1F_ED: TI1 Edge Detector
+ * @arg TIM_TS_TI1FP1: Filtered Timer Input 1
+ * @arg TIM_TS_TI2FP2: Filtered Timer Input 2
+ * @arg TIM_TS_ETRF: External Trigger input
+ * @retval None
+ */
+void TIM_SelectInputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource)
+{
+ uint16_t tmpsmcr = 0;
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST6_PERIPH(TIMx));
+ assert_param(IS_TIM_TRIGGER_SELECTION(TIM_InputTriggerSource));
+ /* Get the TIMx SMCR register value */
+ tmpsmcr = TIMx->SMCR;
+ /* Reset the TS Bits */
+ tmpsmcr &= (uint16_t)(~((uint16_t)TIM_SMCR_TS));
+ /* Set the Input Trigger source */
+ tmpsmcr |= TIM_InputTriggerSource;
+ /* Write to TIMx SMCR */
+ TIMx->SMCR = tmpsmcr;
+}
+
+/**
+ * @brief Configures the TIMx Encoder Interface.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+ * @param TIM_EncoderMode: specifies the TIMx Encoder Mode.
+ * This parameter can be one of the following values:
+ * @arg TIM_EncoderMode_TI1: Counter counts on TI1FP1 edge depending on TI2FP2 level.
+ * @arg TIM_EncoderMode_TI2: Counter counts on TI2FP2 edge depending on TI1FP1 level.
+ * @arg TIM_EncoderMode_TI12: Counter counts on both TI1FP1 and TI2FP2 edges depending
+ * on the level of the other input.
+ * @param TIM_IC1Polarity: specifies the IC1 Polarity
+ * This parameter can be one of the following values:
+ * @arg TIM_ICPolarity_Falling: IC Falling edge.
+ * @arg TIM_ICPolarity_Rising: IC Rising edge.
+ * @param TIM_IC2Polarity: specifies the IC2 Polarity
+ * This parameter can be one of the following values:
+ * @arg TIM_ICPolarity_Falling: IC Falling edge.
+ * @arg TIM_ICPolarity_Rising: IC Rising edge.
+ * @retval None
+ */
+void TIM_EncoderInterfaceConfig(TIM_TypeDef* TIMx, uint16_t TIM_EncoderMode,
+ uint16_t TIM_IC1Polarity, uint16_t TIM_IC2Polarity)
+{
+ uint16_t tmpsmcr = 0;
+ uint16_t tmpccmr1 = 0;
+ uint16_t tmpccer = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST5_PERIPH(TIMx));
+ assert_param(IS_TIM_ENCODER_MODE(TIM_EncoderMode));
+ assert_param(IS_TIM_IC_POLARITY(TIM_IC1Polarity));
+ assert_param(IS_TIM_IC_POLARITY(TIM_IC2Polarity));
+
+ /* Get the TIMx SMCR register value */
+ tmpsmcr = TIMx->SMCR;
+
+ /* Get the TIMx CCMR1 register value */
+ tmpccmr1 = TIMx->CCMR1;
+
+ /* Get the TIMx CCER register value */
+ tmpccer = TIMx->CCER;
+
+ /* Set the encoder Mode */
+ tmpsmcr &= (uint16_t)(~((uint16_t)TIM_SMCR_SMS));
+ tmpsmcr |= TIM_EncoderMode;
+
+ /* Select the Capture Compare 1 and the Capture Compare 2 as input */
+ tmpccmr1 &= (uint16_t)(((uint16_t)~((uint16_t)TIM_CCMR1_CC1S)) & (uint16_t)(~((uint16_t)TIM_CCMR1_CC2S)));
+ tmpccmr1 |= TIM_CCMR1_CC1S_0 | TIM_CCMR1_CC2S_0;
+
+ /* Set the TI1 and the TI2 Polarities */
+ tmpccer &= (uint16_t)(((uint16_t)~((uint16_t)TIM_CCER_CC1P)) & ((uint16_t)~((uint16_t)TIM_CCER_CC2P)));
+ tmpccer |= (uint16_t)(TIM_IC1Polarity | (uint16_t)(TIM_IC2Polarity << (uint16_t)4));
+
+ /* Write to TIMx SMCR */
+ TIMx->SMCR = tmpsmcr;
+ /* Write to TIMx CCMR1 */
+ TIMx->CCMR1 = tmpccmr1;
+ /* Write to TIMx CCER */
+ TIMx->CCER = tmpccer;
+}
+
+/**
+ * @brief Forces the TIMx output 1 waveform to active or inactive level.
+ * @param TIMx: where x can be 1 to 17 except 6 and 7 to select the TIM peripheral.
+ * @param TIM_ForcedAction: specifies the forced Action to be set to the output waveform.
+ * This parameter can be one of the following values:
+ * @arg TIM_ForcedAction_Active: Force active level on OC1REF
+ * @arg TIM_ForcedAction_InActive: Force inactive level on OC1REF.
+ * @retval None
+ */
+void TIM_ForcedOC1Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction)
+{
+ uint16_t tmpccmr1 = 0;
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST8_PERIPH(TIMx));
+ assert_param(IS_TIM_FORCED_ACTION(TIM_ForcedAction));
+ tmpccmr1 = TIMx->CCMR1;
+ /* Reset the OC1M Bits */
+ tmpccmr1 &= (uint16_t)~((uint16_t)TIM_CCMR1_OC1M);
+ /* Configure The Forced output Mode */
+ tmpccmr1 |= TIM_ForcedAction;
+ /* Write to TIMx CCMR1 register */
+ TIMx->CCMR1 = tmpccmr1;
+}
+
+/**
+ * @brief Forces the TIMx output 2 waveform to active or inactive level.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 12 or 15 to select the TIM peripheral.
+ * @param TIM_ForcedAction: specifies the forced Action to be set to the output waveform.
+ * This parameter can be one of the following values:
+ * @arg TIM_ForcedAction_Active: Force active level on OC2REF
+ * @arg TIM_ForcedAction_InActive: Force inactive level on OC2REF.
+ * @retval None
+ */
+void TIM_ForcedOC2Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction)
+{
+ uint16_t tmpccmr1 = 0;
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST6_PERIPH(TIMx));
+ assert_param(IS_TIM_FORCED_ACTION(TIM_ForcedAction));
+ tmpccmr1 = TIMx->CCMR1;
+ /* Reset the OC2M Bits */
+ tmpccmr1 &= (uint16_t)~((uint16_t)TIM_CCMR1_OC2M);
+ /* Configure The Forced output Mode */
+ tmpccmr1 |= (uint16_t)(TIM_ForcedAction << 8);
+ /* Write to TIMx CCMR1 register */
+ TIMx->CCMR1 = tmpccmr1;
+}
+
+/**
+ * @brief Forces the TIMx output 3 waveform to active or inactive level.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+ * @param TIM_ForcedAction: specifies the forced Action to be set to the output waveform.
+ * This parameter can be one of the following values:
+ * @arg TIM_ForcedAction_Active: Force active level on OC3REF
+ * @arg TIM_ForcedAction_InActive: Force inactive level on OC3REF.
+ * @retval None
+ */
+void TIM_ForcedOC3Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction)
+{
+ uint16_t tmpccmr2 = 0;
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_TIM_FORCED_ACTION(TIM_ForcedAction));
+ tmpccmr2 = TIMx->CCMR2;
+ /* Reset the OC1M Bits */
+ tmpccmr2 &= (uint16_t)~((uint16_t)TIM_CCMR2_OC3M);
+ /* Configure The Forced output Mode */
+ tmpccmr2 |= TIM_ForcedAction;
+ /* Write to TIMx CCMR2 register */
+ TIMx->CCMR2 = tmpccmr2;
+}
+
+/**
+ * @brief Forces the TIMx output 4 waveform to active or inactive level.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+ * @param TIM_ForcedAction: specifies the forced Action to be set to the output waveform.
+ * This parameter can be one of the following values:
+ * @arg TIM_ForcedAction_Active: Force active level on OC4REF
+ * @arg TIM_ForcedAction_InActive: Force inactive level on OC4REF.
+ * @retval None
+ */
+void TIM_ForcedOC4Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction)
+{
+ uint16_t tmpccmr2 = 0;
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_TIM_FORCED_ACTION(TIM_ForcedAction));
+ tmpccmr2 = TIMx->CCMR2;
+ /* Reset the OC2M Bits */
+ tmpccmr2 &= (uint16_t)~((uint16_t)TIM_CCMR2_OC4M);
+ /* Configure The Forced output Mode */
+ tmpccmr2 |= (uint16_t)(TIM_ForcedAction << 8);
+ /* Write to TIMx CCMR2 register */
+ TIMx->CCMR2 = tmpccmr2;
+}
+
+/**
+ * @brief Enables or disables TIMx peripheral Preload register on ARR.
+ * @param TIMx: where x can be 1 to 17 to select the TIM peripheral.
+ * @param NewState: new state of the TIMx peripheral Preload register
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Set the ARR Preload Bit */
+ TIMx->CR1 |= TIM_CR1_ARPE;
+ }
+ else
+ {
+ /* Reset the ARR Preload Bit */
+ TIMx->CR1 &= (uint16_t)~((uint16_t)TIM_CR1_ARPE);
+ }
+}
+
+/**
+ * @brief Selects the TIM peripheral Commutation event.
+ * @param TIMx: where x can be 1, 8, 15, 16 or 17 to select the TIMx peripheral
+ * @param NewState: new state of the Commutation event.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void TIM_SelectCOM(TIM_TypeDef* TIMx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST2_PERIPH(TIMx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Set the COM Bit */
+ TIMx->CR2 |= TIM_CR2_CCUS;
+ }
+ else
+ {
+ /* Reset the COM Bit */
+ TIMx->CR2 &= (uint16_t)~((uint16_t)TIM_CR2_CCUS);
+ }
+}
+
+/**
+ * @brief Selects the TIMx peripheral Capture Compare DMA source.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 15, 16 or 17 to select
+ * the TIM peripheral.
+ * @param NewState: new state of the Capture Compare DMA source
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void TIM_SelectCCDMA(TIM_TypeDef* TIMx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST4_PERIPH(TIMx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Set the CCDS Bit */
+ TIMx->CR2 |= TIM_CR2_CCDS;
+ }
+ else
+ {
+ /* Reset the CCDS Bit */
+ TIMx->CR2 &= (uint16_t)~((uint16_t)TIM_CR2_CCDS);
+ }
+}
+
+/**
+ * @brief Sets or Resets the TIM peripheral Capture Compare Preload Control bit.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5, 8 or 15
+ * to select the TIMx peripheral
+ * @param NewState: new state of the Capture Compare Preload Control bit
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void TIM_CCPreloadControl(TIM_TypeDef* TIMx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST5_PERIPH(TIMx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Set the CCPC Bit */
+ TIMx->CR2 |= TIM_CR2_CCPC;
+ }
+ else
+ {
+ /* Reset the CCPC Bit */
+ TIMx->CR2 &= (uint16_t)~((uint16_t)TIM_CR2_CCPC);
+ }
+}
+
+/**
+ * @brief Enables or disables the TIMx peripheral Preload register on CCR1.
+ * @param TIMx: where x can be 1 to 17 except 6 and 7 to select the TIM peripheral.
+ * @param TIM_OCPreload: new state of the TIMx peripheral Preload register
+ * This parameter can be one of the following values:
+ * @arg TIM_OCPreload_Enable
+ * @arg TIM_OCPreload_Disable
+ * @retval None
+ */
+void TIM_OC1PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload)
+{
+ uint16_t tmpccmr1 = 0;
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST8_PERIPH(TIMx));
+ assert_param(IS_TIM_OCPRELOAD_STATE(TIM_OCPreload));
+ tmpccmr1 = TIMx->CCMR1;
+ /* Reset the OC1PE Bit */
+ tmpccmr1 &= (uint16_t)~((uint16_t)TIM_CCMR1_OC1PE);
+ /* Enable or Disable the Output Compare Preload feature */
+ tmpccmr1 |= TIM_OCPreload;
+ /* Write to TIMx CCMR1 register */
+ TIMx->CCMR1 = tmpccmr1;
+}
+
+/**
+ * @brief Enables or disables the TIMx peripheral Preload register on CCR2.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 12 or 15 to select
+ * the TIM peripheral.
+ * @param TIM_OCPreload: new state of the TIMx peripheral Preload register
+ * This parameter can be one of the following values:
+ * @arg TIM_OCPreload_Enable
+ * @arg TIM_OCPreload_Disable
+ * @retval None
+ */
+void TIM_OC2PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload)
+{
+ uint16_t tmpccmr1 = 0;
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST6_PERIPH(TIMx));
+ assert_param(IS_TIM_OCPRELOAD_STATE(TIM_OCPreload));
+ tmpccmr1 = TIMx->CCMR1;
+ /* Reset the OC2PE Bit */
+ tmpccmr1 &= (uint16_t)~((uint16_t)TIM_CCMR1_OC2PE);
+ /* Enable or Disable the Output Compare Preload feature */
+ tmpccmr1 |= (uint16_t)(TIM_OCPreload << 8);
+ /* Write to TIMx CCMR1 register */
+ TIMx->CCMR1 = tmpccmr1;
+}
+
+/**
+ * @brief Enables or disables the TIMx peripheral Preload register on CCR3.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+ * @param TIM_OCPreload: new state of the TIMx peripheral Preload register
+ * This parameter can be one of the following values:
+ * @arg TIM_OCPreload_Enable
+ * @arg TIM_OCPreload_Disable
+ * @retval None
+ */
+void TIM_OC3PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload)
+{
+ uint16_t tmpccmr2 = 0;
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_TIM_OCPRELOAD_STATE(TIM_OCPreload));
+ tmpccmr2 = TIMx->CCMR2;
+ /* Reset the OC3PE Bit */
+ tmpccmr2 &= (uint16_t)~((uint16_t)TIM_CCMR2_OC3PE);
+ /* Enable or Disable the Output Compare Preload feature */
+ tmpccmr2 |= TIM_OCPreload;
+ /* Write to TIMx CCMR2 register */
+ TIMx->CCMR2 = tmpccmr2;
+}
+
+/**
+ * @brief Enables or disables the TIMx peripheral Preload register on CCR4.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+ * @param TIM_OCPreload: new state of the TIMx peripheral Preload register
+ * This parameter can be one of the following values:
+ * @arg TIM_OCPreload_Enable
+ * @arg TIM_OCPreload_Disable
+ * @retval None
+ */
+void TIM_OC4PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload)
+{
+ uint16_t tmpccmr2 = 0;
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_TIM_OCPRELOAD_STATE(TIM_OCPreload));
+ tmpccmr2 = TIMx->CCMR2;
+ /* Reset the OC4PE Bit */
+ tmpccmr2 &= (uint16_t)~((uint16_t)TIM_CCMR2_OC4PE);
+ /* Enable or Disable the Output Compare Preload feature */
+ tmpccmr2 |= (uint16_t)(TIM_OCPreload << 8);
+ /* Write to TIMx CCMR2 register */
+ TIMx->CCMR2 = tmpccmr2;
+}
+
+/**
+ * @brief Configures the TIMx Output Compare 1 Fast feature.
+ * @param TIMx: where x can be 1 to 17 except 6 and 7 to select the TIM peripheral.
+ * @param TIM_OCFast: new state of the Output Compare Fast Enable Bit.
+ * This parameter can be one of the following values:
+ * @arg TIM_OCFast_Enable: TIM output compare fast enable
+ * @arg TIM_OCFast_Disable: TIM output compare fast disable
+ * @retval None
+ */
+void TIM_OC1FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast)
+{
+ uint16_t tmpccmr1 = 0;
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST8_PERIPH(TIMx));
+ assert_param(IS_TIM_OCFAST_STATE(TIM_OCFast));
+ /* Get the TIMx CCMR1 register value */
+ tmpccmr1 = TIMx->CCMR1;
+ /* Reset the OC1FE Bit */
+ tmpccmr1 &= (uint16_t)~((uint16_t)TIM_CCMR1_OC1FE);
+ /* Enable or Disable the Output Compare Fast Bit */
+ tmpccmr1 |= TIM_OCFast;
+ /* Write to TIMx CCMR1 */
+ TIMx->CCMR1 = tmpccmr1;
+}
+
+/**
+ * @brief Configures the TIMx Output Compare 2 Fast feature.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 12 or 15 to select
+ * the TIM peripheral.
+ * @param TIM_OCFast: new state of the Output Compare Fast Enable Bit.
+ * This parameter can be one of the following values:
+ * @arg TIM_OCFast_Enable: TIM output compare fast enable
+ * @arg TIM_OCFast_Disable: TIM output compare fast disable
+ * @retval None
+ */
+void TIM_OC2FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast)
+{
+ uint16_t tmpccmr1 = 0;
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST6_PERIPH(TIMx));
+ assert_param(IS_TIM_OCFAST_STATE(TIM_OCFast));
+ /* Get the TIMx CCMR1 register value */
+ tmpccmr1 = TIMx->CCMR1;
+ /* Reset the OC2FE Bit */
+ tmpccmr1 &= (uint16_t)~((uint16_t)TIM_CCMR1_OC2FE);
+ /* Enable or Disable the Output Compare Fast Bit */
+ tmpccmr1 |= (uint16_t)(TIM_OCFast << 8);
+ /* Write to TIMx CCMR1 */
+ TIMx->CCMR1 = tmpccmr1;
+}
+
+/**
+ * @brief Configures the TIMx Output Compare 3 Fast feature.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+ * @param TIM_OCFast: new state of the Output Compare Fast Enable Bit.
+ * This parameter can be one of the following values:
+ * @arg TIM_OCFast_Enable: TIM output compare fast enable
+ * @arg TIM_OCFast_Disable: TIM output compare fast disable
+ * @retval None
+ */
+void TIM_OC3FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast)
+{
+ uint16_t tmpccmr2 = 0;
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_TIM_OCFAST_STATE(TIM_OCFast));
+ /* Get the TIMx CCMR2 register value */
+ tmpccmr2 = TIMx->CCMR2;
+ /* Reset the OC3FE Bit */
+ tmpccmr2 &= (uint16_t)~((uint16_t)TIM_CCMR2_OC3FE);
+ /* Enable or Disable the Output Compare Fast Bit */
+ tmpccmr2 |= TIM_OCFast;
+ /* Write to TIMx CCMR2 */
+ TIMx->CCMR2 = tmpccmr2;
+}
+
+/**
+ * @brief Configures the TIMx Output Compare 4 Fast feature.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+ * @param TIM_OCFast: new state of the Output Compare Fast Enable Bit.
+ * This parameter can be one of the following values:
+ * @arg TIM_OCFast_Enable: TIM output compare fast enable
+ * @arg TIM_OCFast_Disable: TIM output compare fast disable
+ * @retval None
+ */
+void TIM_OC4FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast)
+{
+ uint16_t tmpccmr2 = 0;
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_TIM_OCFAST_STATE(TIM_OCFast));
+ /* Get the TIMx CCMR2 register value */
+ tmpccmr2 = TIMx->CCMR2;
+ /* Reset the OC4FE Bit */
+ tmpccmr2 &= (uint16_t)~((uint16_t)TIM_CCMR2_OC4FE);
+ /* Enable or Disable the Output Compare Fast Bit */
+ tmpccmr2 |= (uint16_t)(TIM_OCFast << 8);
+ /* Write to TIMx CCMR2 */
+ TIMx->CCMR2 = tmpccmr2;
+}
+
+/**
+ * @brief Clears or safeguards the OCREF1 signal on an external event
+ * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+ * @param TIM_OCClear: new state of the Output Compare Clear Enable Bit.
+ * This parameter can be one of the following values:
+ * @arg TIM_OCClear_Enable: TIM Output clear enable
+ * @arg TIM_OCClear_Disable: TIM Output clear disable
+ * @retval None
+ */
+void TIM_ClearOC1Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear)
+{
+ uint16_t tmpccmr1 = 0;
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_TIM_OCCLEAR_STATE(TIM_OCClear));
+
+ tmpccmr1 = TIMx->CCMR1;
+
+ /* Reset the OC1CE Bit */
+ tmpccmr1 &= (uint16_t)~((uint16_t)TIM_CCMR1_OC1CE);
+ /* Enable or Disable the Output Compare Clear Bit */
+ tmpccmr1 |= TIM_OCClear;
+ /* Write to TIMx CCMR1 register */
+ TIMx->CCMR1 = tmpccmr1;
+}
+
+/**
+ * @brief Clears or safeguards the OCREF2 signal on an external event
+ * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+ * @param TIM_OCClear: new state of the Output Compare Clear Enable Bit.
+ * This parameter can be one of the following values:
+ * @arg TIM_OCClear_Enable: TIM Output clear enable
+ * @arg TIM_OCClear_Disable: TIM Output clear disable
+ * @retval None
+ */
+void TIM_ClearOC2Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear)
+{
+ uint16_t tmpccmr1 = 0;
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_TIM_OCCLEAR_STATE(TIM_OCClear));
+ tmpccmr1 = TIMx->CCMR1;
+ /* Reset the OC2CE Bit */
+ tmpccmr1 &= (uint16_t)~((uint16_t)TIM_CCMR1_OC2CE);
+ /* Enable or Disable the Output Compare Clear Bit */
+ tmpccmr1 |= (uint16_t)(TIM_OCClear << 8);
+ /* Write to TIMx CCMR1 register */
+ TIMx->CCMR1 = tmpccmr1;
+}
+
+/**
+ * @brief Clears or safeguards the OCREF3 signal on an external event
+ * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+ * @param TIM_OCClear: new state of the Output Compare Clear Enable Bit.
+ * This parameter can be one of the following values:
+ * @arg TIM_OCClear_Enable: TIM Output clear enable
+ * @arg TIM_OCClear_Disable: TIM Output clear disable
+ * @retval None
+ */
+void TIM_ClearOC3Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear)
+{
+ uint16_t tmpccmr2 = 0;
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_TIM_OCCLEAR_STATE(TIM_OCClear));
+ tmpccmr2 = TIMx->CCMR2;
+ /* Reset the OC3CE Bit */
+ tmpccmr2 &= (uint16_t)~((uint16_t)TIM_CCMR2_OC3CE);
+ /* Enable or Disable the Output Compare Clear Bit */
+ tmpccmr2 |= TIM_OCClear;
+ /* Write to TIMx CCMR2 register */
+ TIMx->CCMR2 = tmpccmr2;
+}
+
+/**
+ * @brief Clears or safeguards the OCREF4 signal on an external event
+ * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+ * @param TIM_OCClear: new state of the Output Compare Clear Enable Bit.
+ * This parameter can be one of the following values:
+ * @arg TIM_OCClear_Enable: TIM Output clear enable
+ * @arg TIM_OCClear_Disable: TIM Output clear disable
+ * @retval None
+ */
+void TIM_ClearOC4Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear)
+{
+ uint16_t tmpccmr2 = 0;
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_TIM_OCCLEAR_STATE(TIM_OCClear));
+ tmpccmr2 = TIMx->CCMR2;
+ /* Reset the OC4CE Bit */
+ tmpccmr2 &= (uint16_t)~((uint16_t)TIM_CCMR2_OC4CE);
+ /* Enable or Disable the Output Compare Clear Bit */
+ tmpccmr2 |= (uint16_t)(TIM_OCClear << 8);
+ /* Write to TIMx CCMR2 register */
+ TIMx->CCMR2 = tmpccmr2;
+}
+
+/**
+ * @brief Configures the TIMx channel 1 polarity.
+ * @param TIMx: where x can be 1 to 17 except 6 and 7 to select the TIM peripheral.
+ * @param TIM_OCPolarity: specifies the OC1 Polarity
+ * This parameter can be one of the following values:
+ * @arg TIM_OCPolarity_High: Output Compare active high
+ * @arg TIM_OCPolarity_Low: Output Compare active low
+ * @retval None
+ */
+void TIM_OC1PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity)
+{
+ uint16_t tmpccer = 0;
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST8_PERIPH(TIMx));
+ assert_param(IS_TIM_OC_POLARITY(TIM_OCPolarity));
+ tmpccer = TIMx->CCER;
+ /* Set or Reset the CC1P Bit */
+ tmpccer &= (uint16_t)~((uint16_t)TIM_CCER_CC1P);
+ tmpccer |= TIM_OCPolarity;
+ /* Write to TIMx CCER register */
+ TIMx->CCER = tmpccer;
+}
+
+/**
+ * @brief Configures the TIMx Channel 1N polarity.
+ * @param TIMx: where x can be 1, 8, 15, 16 or 17 to select the TIM peripheral.
+ * @param TIM_OCNPolarity: specifies the OC1N Polarity
+ * This parameter can be one of the following values:
+ * @arg TIM_OCNPolarity_High: Output Compare active high
+ * @arg TIM_OCNPolarity_Low: Output Compare active low
+ * @retval None
+ */
+void TIM_OC1NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity)
+{
+ uint16_t tmpccer = 0;
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST2_PERIPH(TIMx));
+ assert_param(IS_TIM_OCN_POLARITY(TIM_OCNPolarity));
+
+ tmpccer = TIMx->CCER;
+ /* Set or Reset the CC1NP Bit */
+ tmpccer &= (uint16_t)~((uint16_t)TIM_CCER_CC1NP);
+ tmpccer |= TIM_OCNPolarity;
+ /* Write to TIMx CCER register */
+ TIMx->CCER = tmpccer;
+}
+
+/**
+ * @brief Configures the TIMx channel 2 polarity.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 12 or 15 to select the TIM peripheral.
+ * @param TIM_OCPolarity: specifies the OC2 Polarity
+ * This parameter can be one of the following values:
+ * @arg TIM_OCPolarity_High: Output Compare active high
+ * @arg TIM_OCPolarity_Low: Output Compare active low
+ * @retval None
+ */
+void TIM_OC2PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity)
+{
+ uint16_t tmpccer = 0;
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST6_PERIPH(TIMx));
+ assert_param(IS_TIM_OC_POLARITY(TIM_OCPolarity));
+ tmpccer = TIMx->CCER;
+ /* Set or Reset the CC2P Bit */
+ tmpccer &= (uint16_t)~((uint16_t)TIM_CCER_CC2P);
+ tmpccer |= (uint16_t)(TIM_OCPolarity << 4);
+ /* Write to TIMx CCER register */
+ TIMx->CCER = tmpccer;
+}
+
+/**
+ * @brief Configures the TIMx Channel 2N polarity.
+ * @param TIMx: where x can be 1 or 8 to select the TIM peripheral.
+ * @param TIM_OCNPolarity: specifies the OC2N Polarity
+ * This parameter can be one of the following values:
+ * @arg TIM_OCNPolarity_High: Output Compare active high
+ * @arg TIM_OCNPolarity_Low: Output Compare active low
+ * @retval None
+ */
+void TIM_OC2NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity)
+{
+ uint16_t tmpccer = 0;
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST1_PERIPH(TIMx));
+ assert_param(IS_TIM_OCN_POLARITY(TIM_OCNPolarity));
+
+ tmpccer = TIMx->CCER;
+ /* Set or Reset the CC2NP Bit */
+ tmpccer &= (uint16_t)~((uint16_t)TIM_CCER_CC2NP);
+ tmpccer |= (uint16_t)(TIM_OCNPolarity << 4);
+ /* Write to TIMx CCER register */
+ TIMx->CCER = tmpccer;
+}
+
+/**
+ * @brief Configures the TIMx channel 3 polarity.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+ * @param TIM_OCPolarity: specifies the OC3 Polarity
+ * This parameter can be one of the following values:
+ * @arg TIM_OCPolarity_High: Output Compare active high
+ * @arg TIM_OCPolarity_Low: Output Compare active low
+ * @retval None
+ */
+void TIM_OC3PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity)
+{
+ uint16_t tmpccer = 0;
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_TIM_OC_POLARITY(TIM_OCPolarity));
+ tmpccer = TIMx->CCER;
+ /* Set or Reset the CC3P Bit */
+ tmpccer &= (uint16_t)~((uint16_t)TIM_CCER_CC3P);
+ tmpccer |= (uint16_t)(TIM_OCPolarity << 8);
+ /* Write to TIMx CCER register */
+ TIMx->CCER = tmpccer;
+}
+
+/**
+ * @brief Configures the TIMx Channel 3N polarity.
+ * @param TIMx: where x can be 1 or 8 to select the TIM peripheral.
+ * @param TIM_OCNPolarity: specifies the OC3N Polarity
+ * This parameter can be one of the following values:
+ * @arg TIM_OCNPolarity_High: Output Compare active high
+ * @arg TIM_OCNPolarity_Low: Output Compare active low
+ * @retval None
+ */
+void TIM_OC3NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity)
+{
+ uint16_t tmpccer = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST1_PERIPH(TIMx));
+ assert_param(IS_TIM_OCN_POLARITY(TIM_OCNPolarity));
+
+ tmpccer = TIMx->CCER;
+ /* Set or Reset the CC3NP Bit */
+ tmpccer &= (uint16_t)~((uint16_t)TIM_CCER_CC3NP);
+ tmpccer |= (uint16_t)(TIM_OCNPolarity << 8);
+ /* Write to TIMx CCER register */
+ TIMx->CCER = tmpccer;
+}
+
+/**
+ * @brief Configures the TIMx channel 4 polarity.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+ * @param TIM_OCPolarity: specifies the OC4 Polarity
+ * This parameter can be one of the following values:
+ * @arg TIM_OCPolarity_High: Output Compare active high
+ * @arg TIM_OCPolarity_Low: Output Compare active low
+ * @retval None
+ */
+void TIM_OC4PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity)
+{
+ uint16_t tmpccer = 0;
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_TIM_OC_POLARITY(TIM_OCPolarity));
+ tmpccer = TIMx->CCER;
+ /* Set or Reset the CC4P Bit */
+ tmpccer &= (uint16_t)~((uint16_t)TIM_CCER_CC4P);
+ tmpccer |= (uint16_t)(TIM_OCPolarity << 12);
+ /* Write to TIMx CCER register */
+ TIMx->CCER = tmpccer;
+}
+
+/**
+ * @brief Enables or disables the TIM Capture Compare Channel x.
+ * @param TIMx: where x can be 1 to 17 except 6 and 7 to select the TIM peripheral.
+ * @param TIM_Channel: specifies the TIM Channel
+ * This parameter can be one of the following values:
+ * @arg TIM_Channel_1: TIM Channel 1
+ * @arg TIM_Channel_2: TIM Channel 2
+ * @arg TIM_Channel_3: TIM Channel 3
+ * @arg TIM_Channel_4: TIM Channel 4
+ * @param TIM_CCx: specifies the TIM Channel CCxE bit new state.
+ * This parameter can be: TIM_CCx_Enable or TIM_CCx_Disable.
+ * @retval None
+ */
+void TIM_CCxCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCx)
+{
+ uint16_t tmp = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST8_PERIPH(TIMx));
+ assert_param(IS_TIM_CHANNEL(TIM_Channel));
+ assert_param(IS_TIM_CCX(TIM_CCx));
+
+ tmp = CCER_CCE_Set << TIM_Channel;
+
+ /* Reset the CCxE Bit */
+ TIMx->CCER &= (uint16_t)~ tmp;
+
+ /* Set or reset the CCxE Bit */
+ TIMx->CCER |= (uint16_t)(TIM_CCx << TIM_Channel);
+}
+
+/**
+ * @brief Enables or disables the TIM Capture Compare Channel xN.
+ * @param TIMx: where x can be 1, 8, 15, 16 or 17 to select the TIM peripheral.
+ * @param TIM_Channel: specifies the TIM Channel
+ * This parameter can be one of the following values:
+ * @arg TIM_Channel_1: TIM Channel 1
+ * @arg TIM_Channel_2: TIM Channel 2
+ * @arg TIM_Channel_3: TIM Channel 3
+ * @param TIM_CCxN: specifies the TIM Channel CCxNE bit new state.
+ * This parameter can be: TIM_CCxN_Enable or TIM_CCxN_Disable.
+ * @retval None
+ */
+void TIM_CCxNCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCxN)
+{
+ uint16_t tmp = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST2_PERIPH(TIMx));
+ assert_param(IS_TIM_COMPLEMENTARY_CHANNEL(TIM_Channel));
+ assert_param(IS_TIM_CCXN(TIM_CCxN));
+
+ tmp = CCER_CCNE_Set << TIM_Channel;
+
+ /* Reset the CCxNE Bit */
+ TIMx->CCER &= (uint16_t) ~tmp;
+
+ /* Set or reset the CCxNE Bit */
+ TIMx->CCER |= (uint16_t)(TIM_CCxN << TIM_Channel);
+}
+
+/**
+ * @brief Selects the TIM Output Compare Mode.
+ * @note This function disables the selected channel before changing the Output
+ * Compare Mode.
+ * User has to enable this channel using TIM_CCxCmd and TIM_CCxNCmd functions.
+ * @param TIMx: where x can be 1 to 17 except 6 and 7 to select the TIM peripheral.
+ * @param TIM_Channel: specifies the TIM Channel
+ * This parameter can be one of the following values:
+ * @arg TIM_Channel_1: TIM Channel 1
+ * @arg TIM_Channel_2: TIM Channel 2
+ * @arg TIM_Channel_3: TIM Channel 3
+ * @arg TIM_Channel_4: TIM Channel 4
+ * @param TIM_OCMode: specifies the TIM Output Compare Mode.
+ * This parameter can be one of the following values:
+ * @arg TIM_OCMode_Timing
+ * @arg TIM_OCMode_Active
+ * @arg TIM_OCMode_Toggle
+ * @arg TIM_OCMode_PWM1
+ * @arg TIM_OCMode_PWM2
+ * @arg TIM_ForcedAction_Active
+ * @arg TIM_ForcedAction_InActive
+ * @retval None
+ */
+void TIM_SelectOCxM(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_OCMode)
+{
+ uint32_t tmp = 0;
+ uint16_t tmp1 = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST8_PERIPH(TIMx));
+ assert_param(IS_TIM_CHANNEL(TIM_Channel));
+ assert_param(IS_TIM_OCM(TIM_OCMode));
+
+ tmp = (uint32_t) TIMx;
+ tmp += CCMR_Offset;
+
+ tmp1 = CCER_CCE_Set << (uint16_t)TIM_Channel;
+
+ /* Disable the Channel: Reset the CCxE Bit */
+ TIMx->CCER &= (uint16_t) ~tmp1;
+
+ if((TIM_Channel == TIM_Channel_1) ||(TIM_Channel == TIM_Channel_3))
+ {
+ tmp += (TIM_Channel>>1);
+
+ /* Reset the OCxM bits in the CCMRx register */
+ *(__IO uint32_t *) tmp &= (uint32_t)~((uint32_t)TIM_CCMR1_OC1M);
+
+ /* Configure the OCxM bits in the CCMRx register */
+ *(__IO uint32_t *) tmp |= TIM_OCMode;
+ }
+ else
+ {
+ tmp += (uint16_t)(TIM_Channel - (uint16_t)4)>> (uint16_t)1;
+
+ /* Reset the OCxM bits in the CCMRx register */
+ *(__IO uint32_t *) tmp &= (uint32_t)~((uint32_t)TIM_CCMR1_OC2M);
+
+ /* Configure the OCxM bits in the CCMRx register */
+ *(__IO uint32_t *) tmp |= (uint16_t)(TIM_OCMode << 8);
+ }
+}
+
+/**
+ * @brief Enables or Disables the TIMx Update event.
+ * @param TIMx: where x can be 1 to 17 to select the TIM peripheral.
+ * @param NewState: new state of the TIMx UDIS bit
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void TIM_UpdateDisableConfig(TIM_TypeDef* TIMx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Set the Update Disable Bit */
+ TIMx->CR1 |= TIM_CR1_UDIS;
+ }
+ else
+ {
+ /* Reset the Update Disable Bit */
+ TIMx->CR1 &= (uint16_t)~((uint16_t)TIM_CR1_UDIS);
+ }
+}
+
+/**
+ * @brief Configures the TIMx Update Request Interrupt source.
+ * @param TIMx: where x can be 1 to 17 to select the TIM peripheral.
+ * @param TIM_UpdateSource: specifies the Update source.
+ * This parameter can be one of the following values:
+ * @arg TIM_UpdateSource_Global: Source of update is the counter overflow/underflow
+ or the setting of UG bit, or an update generation
+ through the slave mode controller.
+ * @arg TIM_UpdateSource_Regular: Source of update is counter overflow/underflow.
+ * @retval None
+ */
+void TIM_UpdateRequestConfig(TIM_TypeDef* TIMx, uint16_t TIM_UpdateSource)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+ assert_param(IS_TIM_UPDATE_SOURCE(TIM_UpdateSource));
+ if (TIM_UpdateSource != TIM_UpdateSource_Global)
+ {
+ /* Set the URS Bit */
+ TIMx->CR1 |= TIM_CR1_URS;
+ }
+ else
+ {
+ /* Reset the URS Bit */
+ TIMx->CR1 &= (uint16_t)~((uint16_t)TIM_CR1_URS);
+ }
+}
+
+/**
+ * @brief Enables or disables the TIMx's Hall sensor interface.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+ * @param NewState: new state of the TIMx Hall sensor interface.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void TIM_SelectHallSensor(TIM_TypeDef* TIMx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST6_PERIPH(TIMx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Set the TI1S Bit */
+ TIMx->CR2 |= TIM_CR2_TI1S;
+ }
+ else
+ {
+ /* Reset the TI1S Bit */
+ TIMx->CR2 &= (uint16_t)~((uint16_t)TIM_CR2_TI1S);
+ }
+}
+
+/**
+ * @brief Selects the TIMx's One Pulse Mode.
+ * @param TIMx: where x can be 1 to 17 to select the TIM peripheral.
+ * @param TIM_OPMode: specifies the OPM Mode to be used.
+ * This parameter can be one of the following values:
+ * @arg TIM_OPMode_Single
+ * @arg TIM_OPMode_Repetitive
+ * @retval None
+ */
+void TIM_SelectOnePulseMode(TIM_TypeDef* TIMx, uint16_t TIM_OPMode)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+ assert_param(IS_TIM_OPM_MODE(TIM_OPMode));
+ /* Reset the OPM Bit */
+ TIMx->CR1 &= (uint16_t)~((uint16_t)TIM_CR1_OPM);
+ /* Configure the OPM Mode */
+ TIMx->CR1 |= TIM_OPMode;
+}
+
+/**
+ * @brief Selects the TIMx Trigger Output Mode.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5, 6, 7, 8, 9, 12 or 15 to select the TIM peripheral.
+ * @param TIM_TRGOSource: specifies the Trigger Output source.
+ * This paramter can be one of the following values:
+ *
+ * - For all TIMx
+ * @arg TIM_TRGOSource_Reset: The UG bit in the TIM_EGR register is used as the trigger output (TRGO).
+ * @arg TIM_TRGOSource_Enable: The Counter Enable CEN is used as the trigger output (TRGO).
+ * @arg TIM_TRGOSource_Update: The update event is selected as the trigger output (TRGO).
+ *
+ * - For all TIMx except TIM6 and TIM7
+ * @arg TIM_TRGOSource_OC1: The trigger output sends a positive pulse when the CC1IF flag
+ * is to be set, as soon as a capture or compare match occurs (TRGO).
+ * @arg TIM_TRGOSource_OC1Ref: OC1REF signal is used as the trigger output (TRGO).
+ * @arg TIM_TRGOSource_OC2Ref: OC2REF signal is used as the trigger output (TRGO).
+ * @arg TIM_TRGOSource_OC3Ref: OC3REF signal is used as the trigger output (TRGO).
+ * @arg TIM_TRGOSource_OC4Ref: OC4REF signal is used as the trigger output (TRGO).
+ *
+ * @retval None
+ */
+void TIM_SelectOutputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_TRGOSource)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST7_PERIPH(TIMx));
+ assert_param(IS_TIM_TRGO_SOURCE(TIM_TRGOSource));
+ /* Reset the MMS Bits */
+ TIMx->CR2 &= (uint16_t)~((uint16_t)TIM_CR2_MMS);
+ /* Select the TRGO source */
+ TIMx->CR2 |= TIM_TRGOSource;
+}
+
+/**
+ * @brief Selects the TIMx Slave Mode.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 12 or 15 to select the TIM peripheral.
+ * @param TIM_SlaveMode: specifies the Timer Slave Mode.
+ * This parameter can be one of the following values:
+ * @arg TIM_SlaveMode_Reset: Rising edge of the selected trigger signal (TRGI) re-initializes
+ * the counter and triggers an update of the registers.
+ * @arg TIM_SlaveMode_Gated: The counter clock is enabled when the trigger signal (TRGI) is high.
+ * @arg TIM_SlaveMode_Trigger: The counter starts at a rising edge of the trigger TRGI.
+ * @arg TIM_SlaveMode_External1: Rising edges of the selected trigger (TRGI) clock the counter.
+ * @retval None
+ */
+void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST6_PERIPH(TIMx));
+ assert_param(IS_TIM_SLAVE_MODE(TIM_SlaveMode));
+ /* Reset the SMS Bits */
+ TIMx->SMCR &= (uint16_t)~((uint16_t)TIM_SMCR_SMS);
+ /* Select the Slave Mode */
+ TIMx->SMCR |= TIM_SlaveMode;
+}
+
+/**
+ * @brief Sets or Resets the TIMx Master/Slave Mode.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 12 or 15 to select the TIM peripheral.
+ * @param TIM_MasterSlaveMode: specifies the Timer Master Slave Mode.
+ * This parameter can be one of the following values:
+ * @arg TIM_MasterSlaveMode_Enable: synchronization between the current timer
+ * and its slaves (through TRGO).
+ * @arg TIM_MasterSlaveMode_Disable: No action
+ * @retval None
+ */
+void TIM_SelectMasterSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_MasterSlaveMode)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST6_PERIPH(TIMx));
+ assert_param(IS_TIM_MSM_STATE(TIM_MasterSlaveMode));
+ /* Reset the MSM Bit */
+ TIMx->SMCR &= (uint16_t)~((uint16_t)TIM_SMCR_MSM);
+
+ /* Set or Reset the MSM Bit */
+ TIMx->SMCR |= TIM_MasterSlaveMode;
+}
+
+/**
+ * @brief Sets the TIMx Counter Register value
+ * @param TIMx: where x can be 1 to 17 to select the TIM peripheral.
+ * @param Counter: specifies the Counter register new value.
+ * @retval None
+ */
+void TIM_SetCounter(TIM_TypeDef* TIMx, uint16_t Counter)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+ /* Set the Counter Register value */
+ TIMx->CNT = Counter;
+}
+
+/**
+ * @brief Sets the TIMx Autoreload Register value
+ * @param TIMx: where x can be 1 to 17 to select the TIM peripheral.
+ * @param Autoreload: specifies the Autoreload register new value.
+ * @retval None
+ */
+void TIM_SetAutoreload(TIM_TypeDef* TIMx, uint16_t Autoreload)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+ /* Set the Autoreload Register value */
+ TIMx->ARR = Autoreload;
+}
+
+/**
+ * @brief Sets the TIMx Capture Compare1 Register value
+ * @param TIMx: where x can be 1 to 17 except 6 and 7 to select the TIM peripheral.
+ * @param Compare1: specifies the Capture Compare1 register new value.
+ * @retval None
+ */
+void TIM_SetCompare1(TIM_TypeDef* TIMx, uint16_t Compare1)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST8_PERIPH(TIMx));
+ /* Set the Capture Compare1 Register value */
+ TIMx->CCR1 = Compare1;
+}
+
+/**
+ * @brief Sets the TIMx Capture Compare2 Register value
+ * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 12 or 15 to select the TIM peripheral.
+ * @param Compare2: specifies the Capture Compare2 register new value.
+ * @retval None
+ */
+void TIM_SetCompare2(TIM_TypeDef* TIMx, uint16_t Compare2)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST6_PERIPH(TIMx));
+ /* Set the Capture Compare2 Register value */
+ TIMx->CCR2 = Compare2;
+}
+
+/**
+ * @brief Sets the TIMx Capture Compare3 Register value
+ * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+ * @param Compare3: specifies the Capture Compare3 register new value.
+ * @retval None
+ */
+void TIM_SetCompare3(TIM_TypeDef* TIMx, uint16_t Compare3)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ /* Set the Capture Compare3 Register value */
+ TIMx->CCR3 = Compare3;
+}
+
+/**
+ * @brief Sets the TIMx Capture Compare4 Register value
+ * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+ * @param Compare4: specifies the Capture Compare4 register new value.
+ * @retval None
+ */
+void TIM_SetCompare4(TIM_TypeDef* TIMx, uint16_t Compare4)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ /* Set the Capture Compare4 Register value */
+ TIMx->CCR4 = Compare4;
+}
+
+/**
+ * @brief Sets the TIMx Input Capture 1 prescaler.
+ * @param TIMx: where x can be 1 to 17 except 6 and 7 to select the TIM peripheral.
+ * @param TIM_ICPSC: specifies the Input Capture1 prescaler new value.
+ * This parameter can be one of the following values:
+ * @arg TIM_ICPSC_DIV1: no prescaler
+ * @arg TIM_ICPSC_DIV2: capture is done once every 2 events
+ * @arg TIM_ICPSC_DIV4: capture is done once every 4 events
+ * @arg TIM_ICPSC_DIV8: capture is done once every 8 events
+ * @retval None
+ */
+void TIM_SetIC1Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST8_PERIPH(TIMx));
+ assert_param(IS_TIM_IC_PRESCALER(TIM_ICPSC));
+ /* Reset the IC1PSC Bits */
+ TIMx->CCMR1 &= (uint16_t)~((uint16_t)TIM_CCMR1_IC1PSC);
+ /* Set the IC1PSC value */
+ TIMx->CCMR1 |= TIM_ICPSC;
+}
+
+/**
+ * @brief Sets the TIMx Input Capture 2 prescaler.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 12 or 15 to select the TIM peripheral.
+ * @param TIM_ICPSC: specifies the Input Capture2 prescaler new value.
+ * This parameter can be one of the following values:
+ * @arg TIM_ICPSC_DIV1: no prescaler
+ * @arg TIM_ICPSC_DIV2: capture is done once every 2 events
+ * @arg TIM_ICPSC_DIV4: capture is done once every 4 events
+ * @arg TIM_ICPSC_DIV8: capture is done once every 8 events
+ * @retval None
+ */
+void TIM_SetIC2Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST6_PERIPH(TIMx));
+ assert_param(IS_TIM_IC_PRESCALER(TIM_ICPSC));
+ /* Reset the IC2PSC Bits */
+ TIMx->CCMR1 &= (uint16_t)~((uint16_t)TIM_CCMR1_IC2PSC);
+ /* Set the IC2PSC value */
+ TIMx->CCMR1 |= (uint16_t)(TIM_ICPSC << 8);
+}
+
+/**
+ * @brief Sets the TIMx Input Capture 3 prescaler.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+ * @param TIM_ICPSC: specifies the Input Capture3 prescaler new value.
+ * This parameter can be one of the following values:
+ * @arg TIM_ICPSC_DIV1: no prescaler
+ * @arg TIM_ICPSC_DIV2: capture is done once every 2 events
+ * @arg TIM_ICPSC_DIV4: capture is done once every 4 events
+ * @arg TIM_ICPSC_DIV8: capture is done once every 8 events
+ * @retval None
+ */
+void TIM_SetIC3Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_TIM_IC_PRESCALER(TIM_ICPSC));
+ /* Reset the IC3PSC Bits */
+ TIMx->CCMR2 &= (uint16_t)~((uint16_t)TIM_CCMR2_IC3PSC);
+ /* Set the IC3PSC value */
+ TIMx->CCMR2 |= TIM_ICPSC;
+}
+
+/**
+ * @brief Sets the TIMx Input Capture 4 prescaler.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+ * @param TIM_ICPSC: specifies the Input Capture4 prescaler new value.
+ * This parameter can be one of the following values:
+ * @arg TIM_ICPSC_DIV1: no prescaler
+ * @arg TIM_ICPSC_DIV2: capture is done once every 2 events
+ * @arg TIM_ICPSC_DIV4: capture is done once every 4 events
+ * @arg TIM_ICPSC_DIV8: capture is done once every 8 events
+ * @retval None
+ */
+void TIM_SetIC4Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_TIM_IC_PRESCALER(TIM_ICPSC));
+ /* Reset the IC4PSC Bits */
+ TIMx->CCMR2 &= (uint16_t)~((uint16_t)TIM_CCMR2_IC4PSC);
+ /* Set the IC4PSC value */
+ TIMx->CCMR2 |= (uint16_t)(TIM_ICPSC << 8);
+}
+
+/**
+ * @brief Sets the TIMx Clock Division value.
+ * @param TIMx: where x can be 1 to 17 except 6 and 7 to select
+ * the TIM peripheral.
+ * @param TIM_CKD: specifies the clock division value.
+ * This parameter can be one of the following value:
+ * @arg TIM_CKD_DIV1: TDTS = Tck_tim
+ * @arg TIM_CKD_DIV2: TDTS = 2*Tck_tim
+ * @arg TIM_CKD_DIV4: TDTS = 4*Tck_tim
+ * @retval None
+ */
+void TIM_SetClockDivision(TIM_TypeDef* TIMx, uint16_t TIM_CKD)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST8_PERIPH(TIMx));
+ assert_param(IS_TIM_CKD_DIV(TIM_CKD));
+ /* Reset the CKD Bits */
+ TIMx->CR1 &= (uint16_t)~((uint16_t)TIM_CR1_CKD);
+ /* Set the CKD value */
+ TIMx->CR1 |= TIM_CKD;
+}
+
+/**
+ * @brief Gets the TIMx Input Capture 1 value.
+ * @param TIMx: where x can be 1 to 17 except 6 and 7 to select the TIM peripheral.
+ * @retval Capture Compare 1 Register value.
+ */
+uint16_t TIM_GetCapture1(TIM_TypeDef* TIMx)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST8_PERIPH(TIMx));
+ /* Get the Capture 1 Register value */
+ return TIMx->CCR1;
+}
+
+/**
+ * @brief Gets the TIMx Input Capture 2 value.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 12 or 15 to select the TIM peripheral.
+ * @retval Capture Compare 2 Register value.
+ */
+uint16_t TIM_GetCapture2(TIM_TypeDef* TIMx)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST6_PERIPH(TIMx));
+ /* Get the Capture 2 Register value */
+ return TIMx->CCR2;
+}
+
+/**
+ * @brief Gets the TIMx Input Capture 3 value.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+ * @retval Capture Compare 3 Register value.
+ */
+uint16_t TIM_GetCapture3(TIM_TypeDef* TIMx)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ /* Get the Capture 3 Register value */
+ return TIMx->CCR3;
+}
+
+/**
+ * @brief Gets the TIMx Input Capture 4 value.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+ * @retval Capture Compare 4 Register value.
+ */
+uint16_t TIM_GetCapture4(TIM_TypeDef* TIMx)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ /* Get the Capture 4 Register value */
+ return TIMx->CCR4;
+}
+
+/**
+ * @brief Gets the TIMx Counter value.
+ * @param TIMx: where x can be 1 to 17 to select the TIM peripheral.
+ * @retval Counter Register value.
+ */
+uint16_t TIM_GetCounter(TIM_TypeDef* TIMx)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+ /* Get the Counter Register value */
+ return TIMx->CNT;
+}
+
+/**
+ * @brief Gets the TIMx Prescaler value.
+ * @param TIMx: where x can be 1 to 17 to select the TIM peripheral.
+ * @retval Prescaler Register value.
+ */
+uint16_t TIM_GetPrescaler(TIM_TypeDef* TIMx)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+ /* Get the Prescaler Register value */
+ return TIMx->PSC;
+}
+
+/**
+ * @brief Checks whether the specified TIM flag is set or not.
+ * @param TIMx: where x can be 1 to 17 to select the TIM peripheral.
+ * @param TIM_FLAG: specifies the flag to check.
+ * This parameter can be one of the following values:
+ * @arg TIM_FLAG_Update: TIM update Flag
+ * @arg TIM_FLAG_CC1: TIM Capture Compare 1 Flag
+ * @arg TIM_FLAG_CC2: TIM Capture Compare 2 Flag
+ * @arg TIM_FLAG_CC3: TIM Capture Compare 3 Flag
+ * @arg TIM_FLAG_CC4: TIM Capture Compare 4 Flag
+ * @arg TIM_FLAG_COM: TIM Commutation Flag
+ * @arg TIM_FLAG_Trigger: TIM Trigger Flag
+ * @arg TIM_FLAG_Break: TIM Break Flag
+ * @arg TIM_FLAG_CC1OF: TIM Capture Compare 1 overcapture Flag
+ * @arg TIM_FLAG_CC2OF: TIM Capture Compare 2 overcapture Flag
+ * @arg TIM_FLAG_CC3OF: TIM Capture Compare 3 overcapture Flag
+ * @arg TIM_FLAG_CC4OF: TIM Capture Compare 4 overcapture Flag
+ * @note
+ * - TIM6 and TIM7 can have only one update flag.
+ * - TIM9, TIM12 and TIM15 can have only TIM_FLAG_Update, TIM_FLAG_CC1,
+ * TIM_FLAG_CC2 or TIM_FLAG_Trigger.
+ * - TIM10, TIM11, TIM13, TIM14, TIM16 and TIM17 can have TIM_FLAG_Update or TIM_FLAG_CC1.
+ * - TIM_FLAG_Break is used only with TIM1, TIM8 and TIM15.
+ * - TIM_FLAG_COM is used only with TIM1, TIM8, TIM15, TIM16 and TIM17.
+ * @retval The new state of TIM_FLAG (SET or RESET).
+ */
+FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint16_t TIM_FLAG)
+{
+ ITStatus bitstatus = RESET;
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+ assert_param(IS_TIM_GET_FLAG(TIM_FLAG));
+
+ if ((TIMx->SR & TIM_FLAG) != (uint16_t)RESET)
+ {
+ bitstatus = SET;
+ }
+ else
+ {
+ bitstatus = RESET;
+ }
+ return bitstatus;
+}
+
+/**
+ * @brief Clears the TIMx's pending flags.
+ * @param TIMx: where x can be 1 to 17 to select the TIM peripheral.
+ * @param TIM_FLAG: specifies the flag bit to clear.
+ * This parameter can be any combination of the following values:
+ * @arg TIM_FLAG_Update: TIM update Flag
+ * @arg TIM_FLAG_CC1: TIM Capture Compare 1 Flag
+ * @arg TIM_FLAG_CC2: TIM Capture Compare 2 Flag
+ * @arg TIM_FLAG_CC3: TIM Capture Compare 3 Flag
+ * @arg TIM_FLAG_CC4: TIM Capture Compare 4 Flag
+ * @arg TIM_FLAG_COM: TIM Commutation Flag
+ * @arg TIM_FLAG_Trigger: TIM Trigger Flag
+ * @arg TIM_FLAG_Break: TIM Break Flag
+ * @arg TIM_FLAG_CC1OF: TIM Capture Compare 1 overcapture Flag
+ * @arg TIM_FLAG_CC2OF: TIM Capture Compare 2 overcapture Flag
+ * @arg TIM_FLAG_CC3OF: TIM Capture Compare 3 overcapture Flag
+ * @arg TIM_FLAG_CC4OF: TIM Capture Compare 4 overcapture Flag
+ * @note
+ * - TIM6 and TIM7 can have only one update flag.
+ * - TIM9, TIM12 and TIM15 can have only TIM_FLAG_Update, TIM_FLAG_CC1,
+ * TIM_FLAG_CC2 or TIM_FLAG_Trigger.
+ * - TIM10, TIM11, TIM13, TIM14, TIM16 and TIM17 can have TIM_FLAG_Update or TIM_FLAG_CC1.
+ * - TIM_FLAG_Break is used only with TIM1, TIM8 and TIM15.
+ * - TIM_FLAG_COM is used only with TIM1, TIM8, TIM15, TIM16 and TIM17.
+ * @retval None
+ */
+void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+ assert_param(IS_TIM_CLEAR_FLAG(TIM_FLAG));
+
+ /* Clear the flags */
+ TIMx->SR = (uint16_t)~TIM_FLAG;
+}
+
+/**
+ * @brief Checks whether the TIM interrupt has occurred or not.
+ * @param TIMx: where x can be 1 to 17 to select the TIM peripheral.
+ * @param TIM_IT: specifies the TIM interrupt source to check.
+ * This parameter can be one of the following values:
+ * @arg TIM_IT_Update: TIM update Interrupt source
+ * @arg TIM_IT_CC1: TIM Capture Compare 1 Interrupt source
+ * @arg TIM_IT_CC2: TIM Capture Compare 2 Interrupt source
+ * @arg TIM_IT_CC3: TIM Capture Compare 3 Interrupt source
+ * @arg TIM_IT_CC4: TIM Capture Compare 4 Interrupt source
+ * @arg TIM_IT_COM: TIM Commutation Interrupt source
+ * @arg TIM_IT_Trigger: TIM Trigger Interrupt source
+ * @arg TIM_IT_Break: TIM Break Interrupt source
+ * @note
+ * - TIM6 and TIM7 can generate only an update interrupt.
+ * - TIM9, TIM12 and TIM15 can have only TIM_IT_Update, TIM_IT_CC1,
+ * TIM_IT_CC2 or TIM_IT_Trigger.
+ * - TIM10, TIM11, TIM13, TIM14, TIM16 and TIM17 can have TIM_IT_Update or TIM_IT_CC1.
+ * - TIM_IT_Break is used only with TIM1, TIM8 and TIM15.
+ * - TIM_IT_COM is used only with TIM1, TIM8, TIM15, TIM16 and TIM17.
+ * @retval The new state of the TIM_IT(SET or RESET).
+ */
+ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT)
+{
+ ITStatus bitstatus = RESET;
+ uint16_t itstatus = 0x0, itenable = 0x0;
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+ assert_param(IS_TIM_GET_IT(TIM_IT));
+
+ itstatus = TIMx->SR & TIM_IT;
+
+ itenable = TIMx->DIER & TIM_IT;
+ if ((itstatus != (uint16_t)RESET) && (itenable != (uint16_t)RESET))
+ {
+ bitstatus = SET;
+ }
+ else
+ {
+ bitstatus = RESET;
+ }
+ return bitstatus;
+}
+
+/**
+ * @brief Clears the TIMx's interrupt pending bits.
+ * @param TIMx: where x can be 1 to 17 to select the TIM peripheral.
+ * @param TIM_IT: specifies the pending bit to clear.
+ * This parameter can be any combination of the following values:
+ * @arg TIM_IT_Update: TIM1 update Interrupt source
+ * @arg TIM_IT_CC1: TIM Capture Compare 1 Interrupt source
+ * @arg TIM_IT_CC2: TIM Capture Compare 2 Interrupt source
+ * @arg TIM_IT_CC3: TIM Capture Compare 3 Interrupt source
+ * @arg TIM_IT_CC4: TIM Capture Compare 4 Interrupt source
+ * @arg TIM_IT_COM: TIM Commutation Interrupt source
+ * @arg TIM_IT_Trigger: TIM Trigger Interrupt source
+ * @arg TIM_IT_Break: TIM Break Interrupt source
+ * @note
+ * - TIM6 and TIM7 can generate only an update interrupt.
+ * - TIM9, TIM12 and TIM15 can have only TIM_IT_Update, TIM_IT_CC1,
+ * TIM_IT_CC2 or TIM_IT_Trigger.
+ * - TIM10, TIM11, TIM13, TIM14, TIM16 and TIM17 can have TIM_IT_Update or TIM_IT_CC1.
+ * - TIM_IT_Break is used only with TIM1, TIM8 and TIM15.
+ * - TIM_IT_COM is used only with TIM1, TIM8, TIM15, TIM16 and TIM17.
+ * @retval None
+ */
+void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+ assert_param(IS_TIM_IT(TIM_IT));
+ /* Clear the IT pending Bit */
+ TIMx->SR = (uint16_t)~TIM_IT;
+}
+
+/**
+ * @brief Configure the TI1 as Input.
+ * @param TIMx: where x can be 1 to 17 except 6 and 7 to select the TIM peripheral.
+ * @param TIM_ICPolarity : The Input Polarity.
+ * This parameter can be one of the following values:
+ * @arg TIM_ICPolarity_Rising
+ * @arg TIM_ICPolarity_Falling
+ * @param TIM_ICSelection: specifies the input to be used.
+ * This parameter can be one of the following values:
+ * @arg TIM_ICSelection_DirectTI: TIM Input 1 is selected to be connected to IC1.
+ * @arg TIM_ICSelection_IndirectTI: TIM Input 1 is selected to be connected to IC2.
+ * @arg TIM_ICSelection_TRC: TIM Input 1 is selected to be connected to TRC.
+ * @param TIM_ICFilter: Specifies the Input Capture Filter.
+ * This parameter must be a value between 0x00 and 0x0F.
+ * @retval None
+ */
+static void TI1_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection,
+ uint16_t TIM_ICFilter)
+{
+ uint16_t tmpccmr1 = 0, tmpccer = 0;
+ /* Disable the Channel 1: Reset the CC1E Bit */
+ TIMx->CCER &= (uint16_t)~((uint16_t)TIM_CCER_CC1E);
+ tmpccmr1 = TIMx->CCMR1;
+ tmpccer = TIMx->CCER;
+ /* Select the Input and set the filter */
+ tmpccmr1 &= (uint16_t)(((uint16_t)~((uint16_t)TIM_CCMR1_CC1S)) & ((uint16_t)~((uint16_t)TIM_CCMR1_IC1F)));
+ tmpccmr1 |= (uint16_t)(TIM_ICSelection | (uint16_t)(TIM_ICFilter << (uint16_t)4));
+
+ if((TIMx == TIM1) || (TIMx == TIM8) || (TIMx == TIM2) || (TIMx == TIM3) ||
+ (TIMx == TIM4) ||(TIMx == TIM5))
+ {
+ /* Select the Polarity and set the CC1E Bit */
+ tmpccer &= (uint16_t)~((uint16_t)(TIM_CCER_CC1P));
+ tmpccer |= (uint16_t)(TIM_ICPolarity | (uint16_t)TIM_CCER_CC1E);
+ }
+ else
+ {
+ /* Select the Polarity and set the CC1E Bit */
+ tmpccer &= (uint16_t)~((uint16_t)(TIM_CCER_CC1P | TIM_CCER_CC1NP));
+ tmpccer |= (uint16_t)(TIM_ICPolarity | (uint16_t)TIM_CCER_CC1E);
+ }
+
+ /* Write to TIMx CCMR1 and CCER registers */
+ TIMx->CCMR1 = tmpccmr1;
+ TIMx->CCER = tmpccer;
+}
+
+/**
+ * @brief Configure the TI2 as Input.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 12 or 15 to select the TIM peripheral.
+ * @param TIM_ICPolarity : The Input Polarity.
+ * This parameter can be one of the following values:
+ * @arg TIM_ICPolarity_Rising
+ * @arg TIM_ICPolarity_Falling
+ * @param TIM_ICSelection: specifies the input to be used.
+ * This parameter can be one of the following values:
+ * @arg TIM_ICSelection_DirectTI: TIM Input 2 is selected to be connected to IC2.
+ * @arg TIM_ICSelection_IndirectTI: TIM Input 2 is selected to be connected to IC1.
+ * @arg TIM_ICSelection_TRC: TIM Input 2 is selected to be connected to TRC.
+ * @param TIM_ICFilter: Specifies the Input Capture Filter.
+ * This parameter must be a value between 0x00 and 0x0F.
+ * @retval None
+ */
+static void TI2_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection,
+ uint16_t TIM_ICFilter)
+{
+ uint16_t tmpccmr1 = 0, tmpccer = 0, tmp = 0;
+ /* Disable the Channel 2: Reset the CC2E Bit */
+ TIMx->CCER &= (uint16_t)~((uint16_t)TIM_CCER_CC2E);
+ tmpccmr1 = TIMx->CCMR1;
+ tmpccer = TIMx->CCER;
+ tmp = (uint16_t)(TIM_ICPolarity << 4);
+ /* Select the Input and set the filter */
+ tmpccmr1 &= (uint16_t)(((uint16_t)~((uint16_t)TIM_CCMR1_CC2S)) & ((uint16_t)~((uint16_t)TIM_CCMR1_IC2F)));
+ tmpccmr1 |= (uint16_t)(TIM_ICFilter << 12);
+ tmpccmr1 |= (uint16_t)(TIM_ICSelection << 8);
+
+ if((TIMx == TIM1) || (TIMx == TIM8) || (TIMx == TIM2) || (TIMx == TIM3) ||
+ (TIMx == TIM4) ||(TIMx == TIM5))
+ {
+ /* Select the Polarity and set the CC2E Bit */
+ tmpccer &= (uint16_t)~((uint16_t)(TIM_CCER_CC2P));
+ tmpccer |= (uint16_t)(tmp | (uint16_t)TIM_CCER_CC2E);
+ }
+ else
+ {
+ /* Select the Polarity and set the CC2E Bit */
+ tmpccer &= (uint16_t)~((uint16_t)(TIM_CCER_CC2P | TIM_CCER_CC2NP));
+ tmpccer |= (uint16_t)(TIM_ICPolarity | (uint16_t)TIM_CCER_CC2E);
+ }
+
+ /* Write to TIMx CCMR1 and CCER registers */
+ TIMx->CCMR1 = tmpccmr1 ;
+ TIMx->CCER = tmpccer;
+}
+
+/**
+ * @brief Configure the TI3 as Input.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+ * @param TIM_ICPolarity : The Input Polarity.
+ * This parameter can be one of the following values:
+ * @arg TIM_ICPolarity_Rising
+ * @arg TIM_ICPolarity_Falling
+ * @param TIM_ICSelection: specifies the input to be used.
+ * This parameter can be one of the following values:
+ * @arg TIM_ICSelection_DirectTI: TIM Input 3 is selected to be connected to IC3.
+ * @arg TIM_ICSelection_IndirectTI: TIM Input 3 is selected to be connected to IC4.
+ * @arg TIM_ICSelection_TRC: TIM Input 3 is selected to be connected to TRC.
+ * @param TIM_ICFilter: Specifies the Input Capture Filter.
+ * This parameter must be a value between 0x00 and 0x0F.
+ * @retval None
+ */
+static void TI3_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection,
+ uint16_t TIM_ICFilter)
+{
+ uint16_t tmpccmr2 = 0, tmpccer = 0, tmp = 0;
+ /* Disable the Channel 3: Reset the CC3E Bit */
+ TIMx->CCER &= (uint16_t)~((uint16_t)TIM_CCER_CC3E);
+ tmpccmr2 = TIMx->CCMR2;
+ tmpccer = TIMx->CCER;
+ tmp = (uint16_t)(TIM_ICPolarity << 8);
+ /* Select the Input and set the filter */
+ tmpccmr2 &= (uint16_t)(((uint16_t)~((uint16_t)TIM_CCMR2_CC3S)) & ((uint16_t)~((uint16_t)TIM_CCMR2_IC3F)));
+ tmpccmr2 |= (uint16_t)(TIM_ICSelection | (uint16_t)(TIM_ICFilter << (uint16_t)4));
+
+ if((TIMx == TIM1) || (TIMx == TIM8) || (TIMx == TIM2) || (TIMx == TIM3) ||
+ (TIMx == TIM4) ||(TIMx == TIM5))
+ {
+ /* Select the Polarity and set the CC3E Bit */
+ tmpccer &= (uint16_t)~((uint16_t)(TIM_CCER_CC3P));
+ tmpccer |= (uint16_t)(tmp | (uint16_t)TIM_CCER_CC3E);
+ }
+ else
+ {
+ /* Select the Polarity and set the CC3E Bit */
+ tmpccer &= (uint16_t)~((uint16_t)(TIM_CCER_CC3P | TIM_CCER_CC3NP));
+ tmpccer |= (uint16_t)(TIM_ICPolarity | (uint16_t)TIM_CCER_CC3E);
+ }
+
+ /* Write to TIMx CCMR2 and CCER registers */
+ TIMx->CCMR2 = tmpccmr2;
+ TIMx->CCER = tmpccer;
+}
+
+/**
+ * @brief Configure the TI4 as Input.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+ * @param TIM_ICPolarity : The Input Polarity.
+ * This parameter can be one of the following values:
+ * @arg TIM_ICPolarity_Rising
+ * @arg TIM_ICPolarity_Falling
+ * @param TIM_ICSelection: specifies the input to be used.
+ * This parameter can be one of the following values:
+ * @arg TIM_ICSelection_DirectTI: TIM Input 4 is selected to be connected to IC4.
+ * @arg TIM_ICSelection_IndirectTI: TIM Input 4 is selected to be connected to IC3.
+ * @arg TIM_ICSelection_TRC: TIM Input 4 is selected to be connected to TRC.
+ * @param TIM_ICFilter: Specifies the Input Capture Filter.
+ * This parameter must be a value between 0x00 and 0x0F.
+ * @retval None
+ */
+static void TI4_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection,
+ uint16_t TIM_ICFilter)
+{
+ uint16_t tmpccmr2 = 0, tmpccer = 0, tmp = 0;
+
+ /* Disable the Channel 4: Reset the CC4E Bit */
+ TIMx->CCER &= (uint16_t)~((uint16_t)TIM_CCER_CC4E);
+ tmpccmr2 = TIMx->CCMR2;
+ tmpccer = TIMx->CCER;
+ tmp = (uint16_t)(TIM_ICPolarity << 12);
+ /* Select the Input and set the filter */
+ tmpccmr2 &= (uint16_t)((uint16_t)(~(uint16_t)TIM_CCMR2_CC4S) & ((uint16_t)~((uint16_t)TIM_CCMR2_IC4F)));
+ tmpccmr2 |= (uint16_t)(TIM_ICSelection << 8);
+ tmpccmr2 |= (uint16_t)(TIM_ICFilter << 12);
+
+ if((TIMx == TIM1) || (TIMx == TIM8) || (TIMx == TIM2) || (TIMx == TIM3) ||
+ (TIMx == TIM4) ||(TIMx == TIM5))
+ {
+ /* Select the Polarity and set the CC4E Bit */
+ tmpccer &= (uint16_t)~((uint16_t)(TIM_CCER_CC4P));
+ tmpccer |= (uint16_t)(tmp | (uint16_t)TIM_CCER_CC4E);
+ }
+ else
+ {
+ /* Select the Polarity and set the CC4E Bit */
+ tmpccer &= (uint16_t)~((uint16_t)(TIM_CCER_CC3P | TIM_CCER_CC4NP));
+ tmpccer |= (uint16_t)(TIM_ICPolarity | (uint16_t)TIM_CCER_CC4E);
+ }
+ /* Write to TIMx CCMR2 and CCER registers */
+ TIMx->CCMR2 = tmpccmr2;
+ TIMx->CCER = tmpccer;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_usart.c b/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_usart.c
new file mode 100644
index 0000000..d38a7a1
--- /dev/null
+++ b/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_usart.c
@@ -0,0 +1,1065 @@
+/**
+ ******************************************************************************
+ * @file stm32f10x_usart.c
+ * @author MCD Application Team
+ * @version V3.6.1
+ * @date 05-March-2012
+ * @brief This file provides all the USART firmware functions.
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f10x_usart.h"
+#include "stm32f10x_rcc.h"
+
+/** @addtogroup STM32F10x_StdPeriph_Driver
+ * @{
+ */
+
+/** @defgroup USART
+ * @brief USART driver modules
+ * @{
+ */
+
+/** @defgroup USART_Private_TypesDefinitions
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup USART_Private_Defines
+ * @{
+ */
+
+#define CR1_UE_Set ((uint16_t)0x2000) /*!< USART Enable Mask */
+#define CR1_UE_Reset ((uint16_t)0xDFFF) /*!< USART Disable Mask */
+
+#define CR1_WAKE_Mask ((uint16_t)0xF7FF) /*!< USART WakeUp Method Mask */
+
+#define CR1_RWU_Set ((uint16_t)0x0002) /*!< USART mute mode Enable Mask */
+#define CR1_RWU_Reset ((uint16_t)0xFFFD) /*!< USART mute mode Enable Mask */
+#define CR1_SBK_Set ((uint16_t)0x0001) /*!< USART Break Character send Mask */
+#define CR1_CLEAR_Mask ((uint16_t)0xE9F3) /*!< USART CR1 Mask */
+#define CR2_Address_Mask ((uint16_t)0xFFF0) /*!< USART address Mask */
+
+#define CR2_LINEN_Set ((uint16_t)0x4000) /*!< USART LIN Enable Mask */
+#define CR2_LINEN_Reset ((uint16_t)0xBFFF) /*!< USART LIN Disable Mask */
+
+#define CR2_LBDL_Mask ((uint16_t)0xFFDF) /*!< USART LIN Break detection Mask */
+#define CR2_STOP_CLEAR_Mask ((uint16_t)0xCFFF) /*!< USART CR2 STOP Bits Mask */
+#define CR2_CLOCK_CLEAR_Mask ((uint16_t)0xF0FF) /*!< USART CR2 Clock Mask */
+
+#define CR3_SCEN_Set ((uint16_t)0x0020) /*!< USART SC Enable Mask */
+#define CR3_SCEN_Reset ((uint16_t)0xFFDF) /*!< USART SC Disable Mask */
+
+#define CR3_NACK_Set ((uint16_t)0x0010) /*!< USART SC NACK Enable Mask */
+#define CR3_NACK_Reset ((uint16_t)0xFFEF) /*!< USART SC NACK Disable Mask */
+
+#define CR3_HDSEL_Set ((uint16_t)0x0008) /*!< USART Half-Duplex Enable Mask */
+#define CR3_HDSEL_Reset ((uint16_t)0xFFF7) /*!< USART Half-Duplex Disable Mask */
+
+#define CR3_IRLP_Mask ((uint16_t)0xFFFB) /*!< USART IrDA LowPower mode Mask */
+#define CR3_CLEAR_Mask ((uint16_t)0xFCFF) /*!< USART CR3 Mask */
+
+#define CR3_IREN_Set ((uint16_t)0x0002) /*!< USART IrDA Enable Mask */
+#define CR3_IREN_Reset ((uint16_t)0xFFFD) /*!< USART IrDA Disable Mask */
+#define GTPR_LSB_Mask ((uint16_t)0x00FF) /*!< Guard Time Register LSB Mask */
+#define GTPR_MSB_Mask ((uint16_t)0xFF00) /*!< Guard Time Register MSB Mask */
+#define IT_Mask ((uint16_t)0x001F) /*!< USART Interrupt Mask */
+
+/* USART OverSampling-8 Mask */
+#define CR1_OVER8_Set ((u16)0x8000) /* USART OVER8 mode Enable Mask */
+#define CR1_OVER8_Reset ((u16)0x7FFF) /* USART OVER8 mode Disable Mask */
+
+/* USART One Bit Sampling Mask */
+#define CR3_ONEBITE_Set ((u16)0x0800) /* USART ONEBITE mode Enable Mask */
+#define CR3_ONEBITE_Reset ((u16)0xF7FF) /* USART ONEBITE mode Disable Mask */
+
+/**
+ * @}
+ */
+
+/** @defgroup USART_Private_Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup USART_Private_Variables
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup USART_Private_FunctionPrototypes
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup USART_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief Deinitializes the USARTx peripheral registers to their default reset values.
+ * @param USARTx: Select the USART or the UART peripheral.
+ * This parameter can be one of the following values:
+ * USART1, USART2, USART3, UART4 or UART5.
+ * @retval None
+ */
+void USART_DeInit(USART_TypeDef* USARTx)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+
+ if (USARTx == USART1)
+ {
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, ENABLE);
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, DISABLE);
+ }
+ else if (USARTx == USART2)
+ {
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2, ENABLE);
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2, DISABLE);
+ }
+ else if (USARTx == USART3)
+ {
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART3, ENABLE);
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART3, DISABLE);
+ }
+ else if (USARTx == UART4)
+ {
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART4, ENABLE);
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART4, DISABLE);
+ }
+ else
+ {
+ if (USARTx == UART5)
+ {
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART5, ENABLE);
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART5, DISABLE);
+ }
+ }
+}
+
+/**
+ * @brief Initializes the USARTx peripheral according to the specified
+ * parameters in the USART_InitStruct .
+ * @param USARTx: Select the USART or the UART peripheral.
+ * This parameter can be one of the following values:
+ * USART1, USART2, USART3, UART4 or UART5.
+ * @param USART_InitStruct: pointer to a USART_InitTypeDef structure
+ * that contains the configuration information for the specified USART
+ * peripheral.
+ * @retval None
+ */
+void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct)
+{
+ uint32_t tmpreg = 0x00, apbclock = 0x00;
+ uint32_t integerdivider = 0x00;
+ uint32_t fractionaldivider = 0x00;
+ uint32_t usartxbase = 0;
+ RCC_ClocksTypeDef RCC_ClocksStatus;
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_BAUDRATE(USART_InitStruct->USART_BaudRate));
+ assert_param(IS_USART_WORD_LENGTH(USART_InitStruct->USART_WordLength));
+ assert_param(IS_USART_STOPBITS(USART_InitStruct->USART_StopBits));
+ assert_param(IS_USART_PARITY(USART_InitStruct->USART_Parity));
+ assert_param(IS_USART_MODE(USART_InitStruct->USART_Mode));
+ assert_param(IS_USART_HARDWARE_FLOW_CONTROL(USART_InitStruct->USART_HardwareFlowControl));
+ /* The hardware flow control is available only for USART1, USART2 and USART3 */
+ if (USART_InitStruct->USART_HardwareFlowControl != USART_HardwareFlowControl_None)
+ {
+ assert_param(IS_USART_123_PERIPH(USARTx));
+ }
+
+ usartxbase = (uint32_t)USARTx;
+
+/*---------------------------- USART CR2 Configuration -----------------------*/
+ tmpreg = USARTx->CR2;
+ /* Clear STOP[13:12] bits */
+ tmpreg &= CR2_STOP_CLEAR_Mask;
+ /* Configure the USART Stop Bits, Clock, CPOL, CPHA and LastBit ------------*/
+ /* Set STOP[13:12] bits according to USART_StopBits value */
+ tmpreg |= (uint32_t)USART_InitStruct->USART_StopBits;
+
+ /* Write to USART CR2 */
+ USARTx->CR2 = (uint16_t)tmpreg;
+
+/*---------------------------- USART CR1 Configuration -----------------------*/
+ tmpreg = USARTx->CR1;
+ /* Clear M, PCE, PS, TE and RE bits */
+ tmpreg &= CR1_CLEAR_Mask;
+ /* Configure the USART Word Length, Parity and mode ----------------------- */
+ /* Set the M bits according to USART_WordLength value */
+ /* Set PCE and PS bits according to USART_Parity value */
+ /* Set TE and RE bits according to USART_Mode value */
+ tmpreg |= (uint32_t)USART_InitStruct->USART_WordLength | USART_InitStruct->USART_Parity |
+ USART_InitStruct->USART_Mode;
+ /* Write to USART CR1 */
+ USARTx->CR1 = (uint16_t)tmpreg;
+
+/*---------------------------- USART CR3 Configuration -----------------------*/
+ tmpreg = USARTx->CR3;
+ /* Clear CTSE and RTSE bits */
+ tmpreg &= CR3_CLEAR_Mask;
+ /* Configure the USART HFC -------------------------------------------------*/
+ /* Set CTSE and RTSE bits according to USART_HardwareFlowControl value */
+ tmpreg |= USART_InitStruct->USART_HardwareFlowControl;
+ /* Write to USART CR3 */
+ USARTx->CR3 = (uint16_t)tmpreg;
+
+/*---------------------------- USART BRR Configuration -----------------------*/
+ /* Configure the USART Baud Rate -------------------------------------------*/
+ RCC_GetClocksFreq(&RCC_ClocksStatus);
+ if (usartxbase == USART1_BASE)
+ {
+ apbclock = RCC_ClocksStatus.PCLK2_Frequency;
+ }
+ else
+ {
+ apbclock = RCC_ClocksStatus.PCLK1_Frequency;
+ }
+
+ /* Determine the integer part */
+ if ((USARTx->CR1 & CR1_OVER8_Set) != 0)
+ {
+ /* Integer part computing in case Oversampling mode is 8 Samples */
+ integerdivider = ((25 * apbclock) / (2 * (USART_InitStruct->USART_BaudRate)));
+ }
+ else /* if ((USARTx->CR1 & CR1_OVER8_Set) == 0) */
+ {
+ /* Integer part computing in case Oversampling mode is 16 Samples */
+ integerdivider = ((25 * apbclock) / (4 * (USART_InitStruct->USART_BaudRate)));
+ }
+ tmpreg = (integerdivider / 100) << 4;
+
+ /* Determine the fractional part */
+ fractionaldivider = integerdivider - (100 * (tmpreg >> 4));
+
+ /* Implement the fractional part in the register */
+ if ((USARTx->CR1 & CR1_OVER8_Set) != 0)
+ {
+ tmpreg |= ((((fractionaldivider * 8) + 50) / 100)) & ((uint8_t)0x07);
+ }
+ else /* if ((USARTx->CR1 & CR1_OVER8_Set) == 0) */
+ {
+ tmpreg |= ((((fractionaldivider * 16) + 50) / 100)) & ((uint8_t)0x0F);
+ }
+
+ /* Write to USART BRR */
+ USARTx->BRR = (uint16_t)tmpreg;
+}
+
+/**
+ * @brief Fills each USART_InitStruct member with its default value.
+ * @param USART_InitStruct: pointer to a USART_InitTypeDef structure
+ * which will be initialized.
+ * @retval None
+ */
+void USART_StructInit(USART_InitTypeDef* USART_InitStruct)
+{
+ /* USART_InitStruct members default value */
+ USART_InitStruct->USART_BaudRate = 9600;
+ USART_InitStruct->USART_WordLength = USART_WordLength_8b;
+ USART_InitStruct->USART_StopBits = USART_StopBits_1;
+ USART_InitStruct->USART_Parity = USART_Parity_No ;
+ USART_InitStruct->USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
+ USART_InitStruct->USART_HardwareFlowControl = USART_HardwareFlowControl_None;
+}
+
+/**
+ * @brief Initializes the USARTx peripheral Clock according to the
+ * specified parameters in the USART_ClockInitStruct .
+ * @param USARTx: where x can be 1, 2, 3 to select the USART peripheral.
+ * @param USART_ClockInitStruct: pointer to a USART_ClockInitTypeDef
+ * structure that contains the configuration information for the specified
+ * USART peripheral.
+ * @note The Smart Card and Synchronous modes are not available for UART4 and UART5.
+ * @retval None
+ */
+void USART_ClockInit(USART_TypeDef* USARTx, USART_ClockInitTypeDef* USART_ClockInitStruct)
+{
+ uint32_t tmpreg = 0x00;
+ /* Check the parameters */
+ assert_param(IS_USART_123_PERIPH(USARTx));
+ assert_param(IS_USART_CLOCK(USART_ClockInitStruct->USART_Clock));
+ assert_param(IS_USART_CPOL(USART_ClockInitStruct->USART_CPOL));
+ assert_param(IS_USART_CPHA(USART_ClockInitStruct->USART_CPHA));
+ assert_param(IS_USART_LASTBIT(USART_ClockInitStruct->USART_LastBit));
+
+/*---------------------------- USART CR2 Configuration -----------------------*/
+ tmpreg = USARTx->CR2;
+ /* Clear CLKEN, CPOL, CPHA and LBCL bits */
+ tmpreg &= CR2_CLOCK_CLEAR_Mask;
+ /* Configure the USART Clock, CPOL, CPHA and LastBit ------------*/
+ /* Set CLKEN bit according to USART_Clock value */
+ /* Set CPOL bit according to USART_CPOL value */
+ /* Set CPHA bit according to USART_CPHA value */
+ /* Set LBCL bit according to USART_LastBit value */
+ tmpreg |= (uint32_t)USART_ClockInitStruct->USART_Clock | USART_ClockInitStruct->USART_CPOL |
+ USART_ClockInitStruct->USART_CPHA | USART_ClockInitStruct->USART_LastBit;
+ /* Write to USART CR2 */
+ USARTx->CR2 = (uint16_t)tmpreg;
+}
+
+/**
+ * @brief Fills each USART_ClockInitStruct member with its default value.
+ * @param USART_ClockInitStruct: pointer to a USART_ClockInitTypeDef
+ * structure which will be initialized.
+ * @retval None
+ */
+void USART_ClockStructInit(USART_ClockInitTypeDef* USART_ClockInitStruct)
+{
+ /* USART_ClockInitStruct members default value */
+ USART_ClockInitStruct->USART_Clock = USART_Clock_Disable;
+ USART_ClockInitStruct->USART_CPOL = USART_CPOL_Low;
+ USART_ClockInitStruct->USART_CPHA = USART_CPHA_1Edge;
+ USART_ClockInitStruct->USART_LastBit = USART_LastBit_Disable;
+}
+
+/**
+ * @brief Enables or disables the specified USART peripheral.
+ * @param USARTx: Select the USART or the UART peripheral.
+ * This parameter can be one of the following values:
+ * USART1, USART2, USART3, UART4 or UART5.
+ * @param NewState: new state of the USARTx peripheral.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected USART by setting the UE bit in the CR1 register */
+ USARTx->CR1 |= CR1_UE_Set;
+ }
+ else
+ {
+ /* Disable the selected USART by clearing the UE bit in the CR1 register */
+ USARTx->CR1 &= CR1_UE_Reset;
+ }
+}
+
+/**
+ * @brief Enables or disables the specified USART interrupts.
+ * @param USARTx: Select the USART or the UART peripheral.
+ * This parameter can be one of the following values:
+ * USART1, USART2, USART3, UART4 or UART5.
+ * @param USART_IT: specifies the USART interrupt sources to be enabled or disabled.
+ * This parameter can be one of the following values:
+ * @arg USART_IT_CTS: CTS change interrupt (not available for UART4 and UART5)
+ * @arg USART_IT_LBD: LIN Break detection interrupt
+ * @arg USART_IT_TXE: Transmit Data Register empty interrupt
+ * @arg USART_IT_TC: Transmission complete interrupt
+ * @arg USART_IT_RXNE: Receive Data register not empty interrupt
+ * @arg USART_IT_IDLE: Idle line detection interrupt
+ * @arg USART_IT_PE: Parity Error interrupt
+ * @arg USART_IT_ERR: Error interrupt(Frame error, noise error, overrun error)
+ * @param NewState: new state of the specified USARTx interrupts.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState)
+{
+ uint32_t usartreg = 0x00, itpos = 0x00, itmask = 0x00;
+ uint32_t usartxbase = 0x00;
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_CONFIG_IT(USART_IT));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ /* The CTS interrupt is not available for UART4 and UART5 */
+ if (USART_IT == USART_IT_CTS)
+ {
+ assert_param(IS_USART_123_PERIPH(USARTx));
+ }
+
+ usartxbase = (uint32_t)USARTx;
+
+ /* Get the USART register index */
+ usartreg = (((uint8_t)USART_IT) >> 0x05);
+
+ /* Get the interrupt position */
+ itpos = USART_IT & IT_Mask;
+ itmask = (((uint32_t)0x01) << itpos);
+
+ if (usartreg == 0x01) /* The IT is in CR1 register */
+ {
+ usartxbase += 0x0C;
+ }
+ else if (usartreg == 0x02) /* The IT is in CR2 register */
+ {
+ usartxbase += 0x10;
+ }
+ else /* The IT is in CR3 register */
+ {
+ usartxbase += 0x14;
+ }
+ if (NewState != DISABLE)
+ {
+ *(__IO uint32_t*)usartxbase |= itmask;
+ }
+ else
+ {
+ *(__IO uint32_t*)usartxbase &= ~itmask;
+ }
+}
+
+/**
+ * @brief Enables or disables the USART�s DMA interface.
+ * @param USARTx: Select the USART or the UART peripheral.
+ * This parameter can be one of the following values:
+ * USART1, USART2, USART3, UART4 or UART5.
+ * @param USART_DMAReq: specifies the DMA request.
+ * This parameter can be any combination of the following values:
+ * @arg USART_DMAReq_Tx: USART DMA transmit request
+ * @arg USART_DMAReq_Rx: USART DMA receive request
+ * @param NewState: new state of the DMA Request sources.
+ * This parameter can be: ENABLE or DISABLE.
+ * @note The DMA mode is not available for UART5 except in the STM32
+ * High density value line devices(STM32F10X_HD_VL).
+ * @retval None
+ */
+void USART_DMACmd(USART_TypeDef* USARTx, uint16_t USART_DMAReq, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_DMAREQ(USART_DMAReq));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Enable the DMA transfer for selected requests by setting the DMAT and/or
+ DMAR bits in the USART CR3 register */
+ USARTx->CR3 |= USART_DMAReq;
+ }
+ else
+ {
+ /* Disable the DMA transfer for selected requests by clearing the DMAT and/or
+ DMAR bits in the USART CR3 register */
+ USARTx->CR3 &= (uint16_t)~USART_DMAReq;
+ }
+}
+
+/**
+ * @brief Sets the address of the USART node.
+ * @param USARTx: Select the USART or the UART peripheral.
+ * This parameter can be one of the following values:
+ * USART1, USART2, USART3, UART4 or UART5.
+ * @param USART_Address: Indicates the address of the USART node.
+ * @retval None
+ */
+void USART_SetAddress(USART_TypeDef* USARTx, uint8_t USART_Address)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_ADDRESS(USART_Address));
+
+ /* Clear the USART address */
+ USARTx->CR2 &= CR2_Address_Mask;
+ /* Set the USART address node */
+ USARTx->CR2 |= USART_Address;
+}
+
+/**
+ * @brief Selects the USART WakeUp method.
+ * @param USARTx: Select the USART or the UART peripheral.
+ * This parameter can be one of the following values:
+ * USART1, USART2, USART3, UART4 or UART5.
+ * @param USART_WakeUp: specifies the USART wakeup method.
+ * This parameter can be one of the following values:
+ * @arg USART_WakeUp_IdleLine: WakeUp by an idle line detection
+ * @arg USART_WakeUp_AddressMark: WakeUp by an address mark
+ * @retval None
+ */
+void USART_WakeUpConfig(USART_TypeDef* USARTx, uint16_t USART_WakeUp)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_WAKEUP(USART_WakeUp));
+
+ USARTx->CR1 &= CR1_WAKE_Mask;
+ USARTx->CR1 |= USART_WakeUp;
+}
+
+/**
+ * @brief Determines if the USART is in mute mode or not.
+ * @param USARTx: Select the USART or the UART peripheral.
+ * This parameter can be one of the following values:
+ * USART1, USART2, USART3, UART4 or UART5.
+ * @param NewState: new state of the USART mute mode.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void USART_ReceiverWakeUpCmd(USART_TypeDef* USARTx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the USART mute mode by setting the RWU bit in the CR1 register */
+ USARTx->CR1 |= CR1_RWU_Set;
+ }
+ else
+ {
+ /* Disable the USART mute mode by clearing the RWU bit in the CR1 register */
+ USARTx->CR1 &= CR1_RWU_Reset;
+ }
+}
+
+/**
+ * @brief Sets the USART LIN Break detection length.
+ * @param USARTx: Select the USART or the UART peripheral.
+ * This parameter can be one of the following values:
+ * USART1, USART2, USART3, UART4 or UART5.
+ * @param USART_LINBreakDetectLength: specifies the LIN break detection length.
+ * This parameter can be one of the following values:
+ * @arg USART_LINBreakDetectLength_10b: 10-bit break detection
+ * @arg USART_LINBreakDetectLength_11b: 11-bit break detection
+ * @retval None
+ */
+void USART_LINBreakDetectLengthConfig(USART_TypeDef* USARTx, uint16_t USART_LINBreakDetectLength)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_LIN_BREAK_DETECT_LENGTH(USART_LINBreakDetectLength));
+
+ USARTx->CR2 &= CR2_LBDL_Mask;
+ USARTx->CR2 |= USART_LINBreakDetectLength;
+}
+
+/**
+ * @brief Enables or disables the USART�s LIN mode.
+ * @param USARTx: Select the USART or the UART peripheral.
+ * This parameter can be one of the following values:
+ * USART1, USART2, USART3, UART4 or UART5.
+ * @param NewState: new state of the USART LIN mode.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void USART_LINCmd(USART_TypeDef* USARTx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the LIN mode by setting the LINEN bit in the CR2 register */
+ USARTx->CR2 |= CR2_LINEN_Set;
+ }
+ else
+ {
+ /* Disable the LIN mode by clearing the LINEN bit in the CR2 register */
+ USARTx->CR2 &= CR2_LINEN_Reset;
+ }
+}
+
+/**
+ * @brief Transmits single data through the USARTx peripheral.
+ * @param USARTx: Select the USART or the UART peripheral.
+ * This parameter can be one of the following values:
+ * USART1, USART2, USART3, UART4 or UART5.
+ * @param Data: the data to transmit.
+ * @retval None
+ */
+void USART_SendData(USART_TypeDef* USARTx, uint16_t Data)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_DATA(Data));
+
+ /* Transmit Data */
+ USARTx->DR = (Data & (uint16_t)0x01FF);
+}
+
+/**
+ * @brief Returns the most recent received data by the USARTx peripheral.
+ * @param USARTx: Select the USART or the UART peripheral.
+ * This parameter can be one of the following values:
+ * USART1, USART2, USART3, UART4 or UART5.
+ * @retval The received data.
+ */
+uint16_t USART_ReceiveData(USART_TypeDef* USARTx)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+
+ /* Receive Data */
+ return (uint16_t)(USARTx->DR & (uint16_t)0x01FF);
+}
+
+/**
+ * @brief Transmits break characters.
+ * @param USARTx: Select the USART or the UART peripheral.
+ * This parameter can be one of the following values:
+ * USART1, USART2, USART3, UART4 or UART5.
+ * @retval None
+ */
+void USART_SendBreak(USART_TypeDef* USARTx)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+
+ /* Send break characters */
+ USARTx->CR1 |= CR1_SBK_Set;
+}
+
+/**
+ * @brief Sets the specified USART guard time.
+ * @param USARTx: where x can be 1, 2 or 3 to select the USART peripheral.
+ * @param USART_GuardTime: specifies the guard time.
+ * @note The guard time bits are not available for UART4 and UART5.
+ * @retval None
+ */
+void USART_SetGuardTime(USART_TypeDef* USARTx, uint8_t USART_GuardTime)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_123_PERIPH(USARTx));
+
+ /* Clear the USART Guard time */
+ USARTx->GTPR &= GTPR_LSB_Mask;
+ /* Set the USART guard time */
+ USARTx->GTPR |= (uint16_t)((uint16_t)USART_GuardTime << 0x08);
+}
+
+/**
+ * @brief Sets the system clock prescaler.
+ * @param USARTx: Select the USART or the UART peripheral.
+ * This parameter can be one of the following values:
+ * USART1, USART2, USART3, UART4 or UART5.
+ * @param USART_Prescaler: specifies the prescaler clock.
+ * @note The function is used for IrDA mode with UART4 and UART5.
+ * @retval None
+ */
+void USART_SetPrescaler(USART_TypeDef* USARTx, uint8_t USART_Prescaler)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+
+ /* Clear the USART prescaler */
+ USARTx->GTPR &= GTPR_MSB_Mask;
+ /* Set the USART prescaler */
+ USARTx->GTPR |= USART_Prescaler;
+}
+
+/**
+ * @brief Enables or disables the USART�s Smart Card mode.
+ * @param USARTx: where x can be 1, 2 or 3 to select the USART peripheral.
+ * @param NewState: new state of the Smart Card mode.
+ * This parameter can be: ENABLE or DISABLE.
+ * @note The Smart Card mode is not available for UART4 and UART5.
+ * @retval None
+ */
+void USART_SmartCardCmd(USART_TypeDef* USARTx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_123_PERIPH(USARTx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Enable the SC mode by setting the SCEN bit in the CR3 register */
+ USARTx->CR3 |= CR3_SCEN_Set;
+ }
+ else
+ {
+ /* Disable the SC mode by clearing the SCEN bit in the CR3 register */
+ USARTx->CR3 &= CR3_SCEN_Reset;
+ }
+}
+
+/**
+ * @brief Enables or disables NACK transmission.
+ * @param USARTx: where x can be 1, 2 or 3 to select the USART peripheral.
+ * @param NewState: new state of the NACK transmission.
+ * This parameter can be: ENABLE or DISABLE.
+ * @note The Smart Card mode is not available for UART4 and UART5.
+ * @retval None
+ */
+void USART_SmartCardNACKCmd(USART_TypeDef* USARTx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_123_PERIPH(USARTx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Enable the NACK transmission by setting the NACK bit in the CR3 register */
+ USARTx->CR3 |= CR3_NACK_Set;
+ }
+ else
+ {
+ /* Disable the NACK transmission by clearing the NACK bit in the CR3 register */
+ USARTx->CR3 &= CR3_NACK_Reset;
+ }
+}
+
+/**
+ * @brief Enables or disables the USART�s Half Duplex communication.
+ * @param USARTx: Select the USART or the UART peripheral.
+ * This parameter can be one of the following values:
+ * USART1, USART2, USART3, UART4 or UART5.
+ * @param NewState: new state of the USART Communication.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void USART_HalfDuplexCmd(USART_TypeDef* USARTx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the Half-Duplex mode by setting the HDSEL bit in the CR3 register */
+ USARTx->CR3 |= CR3_HDSEL_Set;
+ }
+ else
+ {
+ /* Disable the Half-Duplex mode by clearing the HDSEL bit in the CR3 register */
+ USARTx->CR3 &= CR3_HDSEL_Reset;
+ }
+}
+
+
+/**
+ * @brief Enables or disables the USART's 8x oversampling mode.
+ * @param USARTx: Select the USART or the UART peripheral.
+ * This parameter can be one of the following values:
+ * USART1, USART2, USART3, UART4 or UART5.
+ * @param NewState: new state of the USART one bit sampling method.
+ * This parameter can be: ENABLE or DISABLE.
+ * @note
+ * This function has to be called before calling USART_Init()
+ * function in order to have correct baudrate Divider value.
+ * @retval None
+ */
+void USART_OverSampling8Cmd(USART_TypeDef* USARTx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the 8x Oversampling mode by setting the OVER8 bit in the CR1 register */
+ USARTx->CR1 |= CR1_OVER8_Set;
+ }
+ else
+ {
+ /* Disable the 8x Oversampling mode by clearing the OVER8 bit in the CR1 register */
+ USARTx->CR1 &= CR1_OVER8_Reset;
+ }
+}
+
+/**
+ * @brief Enables or disables the USART's one bit sampling method.
+ * @param USARTx: Select the USART or the UART peripheral.
+ * This parameter can be one of the following values:
+ * USART1, USART2, USART3, UART4 or UART5.
+ * @param NewState: new state of the USART one bit sampling method.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void USART_OneBitMethodCmd(USART_TypeDef* USARTx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the one bit method by setting the ONEBITE bit in the CR3 register */
+ USARTx->CR3 |= CR3_ONEBITE_Set;
+ }
+ else
+ {
+ /* Disable tthe one bit method by clearing the ONEBITE bit in the CR3 register */
+ USARTx->CR3 &= CR3_ONEBITE_Reset;
+ }
+}
+
+/**
+ * @brief Configures the USART's IrDA interface.
+ * @param USARTx: Select the USART or the UART peripheral.
+ * This parameter can be one of the following values:
+ * USART1, USART2, USART3, UART4 or UART5.
+ * @param USART_IrDAMode: specifies the IrDA mode.
+ * This parameter can be one of the following values:
+ * @arg USART_IrDAMode_LowPower
+ * @arg USART_IrDAMode_Normal
+ * @retval None
+ */
+void USART_IrDAConfig(USART_TypeDef* USARTx, uint16_t USART_IrDAMode)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_IRDA_MODE(USART_IrDAMode));
+
+ USARTx->CR3 &= CR3_IRLP_Mask;
+ USARTx->CR3 |= USART_IrDAMode;
+}
+
+/**
+ * @brief Enables or disables the USART's IrDA interface.
+ * @param USARTx: Select the USART or the UART peripheral.
+ * This parameter can be one of the following values:
+ * USART1, USART2, USART3, UART4 or UART5.
+ * @param NewState: new state of the IrDA mode.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void USART_IrDACmd(USART_TypeDef* USARTx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the IrDA mode by setting the IREN bit in the CR3 register */
+ USARTx->CR3 |= CR3_IREN_Set;
+ }
+ else
+ {
+ /* Disable the IrDA mode by clearing the IREN bit in the CR3 register */
+ USARTx->CR3 &= CR3_IREN_Reset;
+ }
+}
+
+/**
+ * @brief Checks whether the specified USART flag is set or not.
+ * @param USARTx: Select the USART or the UART peripheral.
+ * This parameter can be one of the following values:
+ * USART1, USART2, USART3, UART4 or UART5.
+ * @param USART_FLAG: specifies the flag to check.
+ * This parameter can be one of the following values:
+ * @arg USART_FLAG_CTS: CTS Change flag (not available for UART4 and UART5)
+ * @arg USART_FLAG_LBD: LIN Break detection flag
+ * @arg USART_FLAG_TXE: Transmit data register empty flag
+ * @arg USART_FLAG_TC: Transmission Complete flag
+ * @arg USART_FLAG_RXNE: Receive data register not empty flag
+ * @arg USART_FLAG_IDLE: Idle Line detection flag
+ * @arg USART_FLAG_ORE: OverRun Error flag
+ * @arg USART_FLAG_NE: Noise Error flag
+ * @arg USART_FLAG_FE: Framing Error flag
+ * @arg USART_FLAG_PE: Parity Error flag
+ * @retval The new state of USART_FLAG (SET or RESET).
+ */
+FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG)
+{
+ FlagStatus bitstatus = RESET;
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_FLAG(USART_FLAG));
+ /* The CTS flag is not available for UART4 and UART5 */
+ if (USART_FLAG == USART_FLAG_CTS)
+ {
+ assert_param(IS_USART_123_PERIPH(USARTx));
+ }
+
+ if ((USARTx->SR & USART_FLAG) != (uint16_t)RESET)
+ {
+ bitstatus = SET;
+ }
+ else
+ {
+ bitstatus = RESET;
+ }
+ return bitstatus;
+}
+
+/**
+ * @brief Clears the USARTx's pending flags.
+ * @param USARTx: Select the USART or the UART peripheral.
+ * This parameter can be one of the following values:
+ * USART1, USART2, USART3, UART4 or UART5.
+ * @param USART_FLAG: specifies the flag to clear.
+ * This parameter can be any combination of the following values:
+ * @arg USART_FLAG_CTS: CTS Change flag (not available for UART4 and UART5).
+ * @arg USART_FLAG_LBD: LIN Break detection flag.
+ * @arg USART_FLAG_TC: Transmission Complete flag.
+ * @arg USART_FLAG_RXNE: Receive data register not empty flag.
+ *
+ * @note
+ * - PE (Parity error), FE (Framing error), NE (Noise error), ORE (OverRun
+ * error) and IDLE (Idle line detected) flags are cleared by software
+ * sequence: a read operation to USART_SR register (USART_GetFlagStatus())
+ * followed by a read operation to USART_DR register (USART_ReceiveData()).
+ * - RXNE flag can be also cleared by a read to the USART_DR register
+ * (USART_ReceiveData()).
+ * - TC flag can be also cleared by software sequence: a read operation to
+ * USART_SR register (USART_GetFlagStatus()) followed by a write operation
+ * to USART_DR register (USART_SendData()).
+ * - TXE flag is cleared only by a write to the USART_DR register
+ * (USART_SendData()).
+ * @retval None
+ */
+void USART_ClearFlag(USART_TypeDef* USARTx, uint16_t USART_FLAG)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_CLEAR_FLAG(USART_FLAG));
+ /* The CTS flag is not available for UART4 and UART5 */
+ if ((USART_FLAG & USART_FLAG_CTS) == USART_FLAG_CTS)
+ {
+ assert_param(IS_USART_123_PERIPH(USARTx));
+ }
+
+ USARTx->SR = (uint16_t)~USART_FLAG;
+}
+
+/**
+ * @brief Checks whether the specified USART interrupt has occurred or not.
+ * @param USARTx: Select the USART or the UART peripheral.
+ * This parameter can be one of the following values:
+ * USART1, USART2, USART3, UART4 or UART5.
+ * @param USART_IT: specifies the USART interrupt source to check.
+ * This parameter can be one of the following values:
+ * @arg USART_IT_CTS: CTS change interrupt (not available for UART4 and UART5)
+ * @arg USART_IT_LBD: LIN Break detection interrupt
+ * @arg USART_IT_TXE: Tansmit Data Register empty interrupt
+ * @arg USART_IT_TC: Transmission complete interrupt
+ * @arg USART_IT_RXNE: Receive Data register not empty interrupt
+ * @arg USART_IT_IDLE: Idle line detection interrupt
+ * @arg USART_IT_ORE_RX : OverRun Error interrupt if the RXNEIE bit is set
+ * @arg USART_IT_ORE_ER : OverRun Error interrupt if the EIE bit is set
+ * @arg USART_IT_NE: Noise Error interrupt
+ * @arg USART_IT_FE: Framing Error interrupt
+ * @arg USART_IT_PE: Parity Error interrupt
+ * @retval The new state of USART_IT (SET or RESET).
+ */
+ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT)
+{
+ uint32_t bitpos = 0x00, itmask = 0x00, usartreg = 0x00;
+ ITStatus bitstatus = RESET;
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_GET_IT(USART_IT));
+ /* The CTS interrupt is not available for UART4 and UART5 */
+ if (USART_IT == USART_IT_CTS)
+ {
+ assert_param(IS_USART_123_PERIPH(USARTx));
+ }
+
+ /* Get the USART register index */
+ usartreg = (((uint8_t)USART_IT) >> 0x05);
+ /* Get the interrupt position */
+ itmask = USART_IT & IT_Mask;
+ itmask = (uint32_t)0x01 << itmask;
+
+ if (usartreg == 0x01) /* The IT is in CR1 register */
+ {
+ itmask &= USARTx->CR1;
+ }
+ else if (usartreg == 0x02) /* The IT is in CR2 register */
+ {
+ itmask &= USARTx->CR2;
+ }
+ else /* The IT is in CR3 register */
+ {
+ itmask &= USARTx->CR3;
+ }
+
+ bitpos = USART_IT >> 0x08;
+ bitpos = (uint32_t)0x01 << bitpos;
+ bitpos &= USARTx->SR;
+ if ((itmask != (uint16_t)RESET)&&(bitpos != (uint16_t)RESET))
+ {
+ bitstatus = SET;
+ }
+ else
+ {
+ bitstatus = RESET;
+ }
+
+ return bitstatus;
+}
+
+/**
+ * @brief Clears the USARTx's interrupt pending bits.
+ * @param USARTx: Select the USART or the UART peripheral.
+ * This parameter can be one of the following values:
+ * USART1, USART2, USART3, UART4 or UART5.
+ * @param USART_IT: specifies the interrupt pending bit to clear.
+ * This parameter can be one of the following values:
+ * @arg USART_IT_CTS: CTS change interrupt (not available for UART4 and UART5)
+ * @arg USART_IT_LBD: LIN Break detection interrupt
+ * @arg USART_IT_TC: Transmission complete interrupt.
+ * @arg USART_IT_RXNE: Receive Data register not empty interrupt.
+ *
+ * @note
+ * - PE (Parity error), FE (Framing error), NE (Noise error), ORE (OverRun
+ * error) and IDLE (Idle line detected) pending bits are cleared by
+ * software sequence: a read operation to USART_SR register
+ * (USART_GetITStatus()) followed by a read operation to USART_DR register
+ * (USART_ReceiveData()).
+ * - RXNE pending bit can be also cleared by a read to the USART_DR register
+ * (USART_ReceiveData()).
+ * - TC pending bit can be also cleared by software sequence: a read
+ * operation to USART_SR register (USART_GetITStatus()) followed by a write
+ * operation to USART_DR register (USART_SendData()).
+ * - TXE pending bit is cleared only by a write to the USART_DR register
+ * (USART_SendData()).
+ * @retval None
+ */
+void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT)
+{
+ uint16_t bitpos = 0x00, itmask = 0x00;
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_CLEAR_IT(USART_IT));
+ /* The CTS interrupt is not available for UART4 and UART5 */
+ if (USART_IT == USART_IT_CTS)
+ {
+ assert_param(IS_USART_123_PERIPH(USARTx));
+ }
+
+ bitpos = USART_IT >> 0x08;
+ itmask = ((uint16_t)0x01 << (uint16_t)bitpos);
+ USARTx->SR = (uint16_t)~itmask;
+}
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_wwdg.c b/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_wwdg.c
new file mode 100644
index 0000000..0115b24
--- /dev/null
+++ b/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_wwdg.c
@@ -0,0 +1,230 @@
+/**
+ ******************************************************************************
+ * @file stm32f10x_wwdg.c
+ * @author MCD Application Team
+ * @version V3.6.1
+ * @date 05-March-2012
+ * @brief This file provides all the WWDG firmware functions.
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f10x_wwdg.h"
+#include "stm32f10x_rcc.h"
+
+/** @addtogroup STM32F10x_StdPeriph_Driver
+ * @{
+ */
+
+/** @defgroup WWDG
+ * @brief WWDG driver modules
+ * @{
+ */
+
+/** @defgroup WWDG_Private_TypesDefinitions
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup WWDG_Private_Defines
+ * @{
+ */
+
+/* ----------- WWDG registers bit address in the alias region ----------- */
+#define WWDG_OFFSET (WWDG_BASE - PERIPH_BASE)
+
+/* Alias word address of EWI bit */
+#define CFR_OFFSET (WWDG_OFFSET + 0x04)
+#define EWI_BitNumber 0x09
+#define CFR_EWI_BB (PERIPH_BB_BASE + (CFR_OFFSET * 32) + (EWI_BitNumber * 4))
+
+/* --------------------- WWDG registers bit mask ------------------------ */
+
+/* CR register bit mask */
+#define CR_WDGA_Set ((uint32_t)0x00000080)
+
+/* CFR register bit mask */
+#define CFR_WDGTB_Mask ((uint32_t)0xFFFFFE7F)
+#define CFR_W_Mask ((uint32_t)0xFFFFFF80)
+#define BIT_Mask ((uint8_t)0x7F)
+
+/**
+ * @}
+ */
+
+/** @defgroup WWDG_Private_Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup WWDG_Private_Variables
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup WWDG_Private_FunctionPrototypes
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup WWDG_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief Deinitializes the WWDG peripheral registers to their default reset values.
+ * @param None
+ * @retval None
+ */
+void WWDG_DeInit(void)
+{
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_WWDG, ENABLE);
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_WWDG, DISABLE);
+}
+
+/**
+ * @brief Sets the WWDG Prescaler.
+ * @param WWDG_Prescaler: specifies the WWDG Prescaler.
+ * This parameter can be one of the following values:
+ * @arg WWDG_Prescaler_1: WWDG counter clock = (PCLK1/4096)/1
+ * @arg WWDG_Prescaler_2: WWDG counter clock = (PCLK1/4096)/2
+ * @arg WWDG_Prescaler_4: WWDG counter clock = (PCLK1/4096)/4
+ * @arg WWDG_Prescaler_8: WWDG counter clock = (PCLK1/4096)/8
+ * @retval None
+ */
+void WWDG_SetPrescaler(uint32_t WWDG_Prescaler)
+{
+ uint32_t tmpreg = 0;
+ /* Check the parameters */
+ assert_param(IS_WWDG_PRESCALER(WWDG_Prescaler));
+ /* Clear WDGTB[1:0] bits */
+ tmpreg = WWDG->CFR & CFR_WDGTB_Mask;
+ /* Set WDGTB[1:0] bits according to WWDG_Prescaler value */
+ tmpreg |= WWDG_Prescaler;
+ /* Store the new value */
+ WWDG->CFR = tmpreg;
+}
+
+/**
+ * @brief Sets the WWDG window value.
+ * @param WindowValue: specifies the window value to be compared to the downcounter.
+ * This parameter value must be lower than 0x80.
+ * @retval None
+ */
+void WWDG_SetWindowValue(uint8_t WindowValue)
+{
+ __IO uint32_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_WWDG_WINDOW_VALUE(WindowValue));
+ /* Clear W[6:0] bits */
+
+ tmpreg = WWDG->CFR & CFR_W_Mask;
+
+ /* Set W[6:0] bits according to WindowValue value */
+ tmpreg |= WindowValue & (uint32_t) BIT_Mask;
+
+ /* Store the new value */
+ WWDG->CFR = tmpreg;
+}
+
+/**
+ * @brief Enables the WWDG Early Wakeup interrupt(EWI).
+ * @param None
+ * @retval None
+ */
+void WWDG_EnableIT(void)
+{
+ *(__IO uint32_t *) CFR_EWI_BB = (uint32_t)ENABLE;
+}
+
+/**
+ * @brief Sets the WWDG counter value.
+ * @param Counter: specifies the watchdog counter value.
+ * This parameter must be a number between 0x40 and 0x7F.
+ * @retval None
+ */
+void WWDG_SetCounter(uint8_t Counter)
+{
+ /* Check the parameters */
+ assert_param(IS_WWDG_COUNTER(Counter));
+ /* Write to T[6:0] bits to configure the counter value, no need to do
+ a read-modify-write; writing a 0 to WDGA bit does nothing */
+ WWDG->CR = Counter & BIT_Mask;
+}
+
+/**
+ * @brief Enables WWDG and load the counter value.
+ * @param Counter: specifies the watchdog counter value.
+ * This parameter must be a number between 0x40 and 0x7F.
+ * @retval None
+ */
+void WWDG_Enable(uint8_t Counter)
+{
+ /* Check the parameters */
+ assert_param(IS_WWDG_COUNTER(Counter));
+ WWDG->CR = CR_WDGA_Set | Counter;
+}
+
+/**
+ * @brief Checks whether the Early Wakeup interrupt flag is set or not.
+ * @param None
+ * @retval The new state of the Early Wakeup interrupt flag (SET or RESET)
+ */
+FlagStatus WWDG_GetFlagStatus(void)
+{
+ return (FlagStatus)(WWDG->SR);
+}
+
+/**
+ * @brief Clears Early Wakeup interrupt flag.
+ * @param None
+ * @retval None
+ */
+void WWDG_ClearFlag(void)
+{
+ WWDG->SR = (uint32_t)RESET;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/Libraries/ioLibrary_Driver/Application/loopback/loopback.c b/Libraries/ioLibrary_Driver/Application/loopback/loopback.c
new file mode 100644
index 0000000..50eaaf7
--- /dev/null
+++ b/Libraries/ioLibrary_Driver/Application/loopback/loopback.c
@@ -0,0 +1,258 @@
+#include
+#include "loopback.h"
+#include "socket.h"
+#include "wizchip_conf.h"
+
+#if LOOPBACK_MODE == LOOPBACK_MAIN_NOBLCOK
+
+int32_t loopback_tcps(uint8_t sn, uint8_t* buf, uint16_t port)
+{
+ int32_t ret;
+ uint16_t size = 0, sentsize=0;
+
+#ifdef _LOOPBACK_DEBUG_
+ uint8_t destip[4];
+ uint16_t destport;
+#endif
+
+ switch(getSn_SR(sn))
+ {
+ case SOCK_ESTABLISHED :
+ if(getSn_IR(sn) & Sn_IR_CON)
+ {
+#ifdef _LOOPBACK_DEBUG_
+ getSn_DIPR(sn, destip);
+ destport = getSn_DPORT(sn);
+
+ printf("%d:Connected - %d.%d.%d.%d : %d\r\n",sn, destip[0], destip[1], destip[2], destip[3], destport);
+#endif
+ setSn_IR(sn,Sn_IR_CON);
+ }
+ if((size = getSn_RX_RSR(sn)) > 0) // Don't need to check SOCKERR_BUSY because it doesn't not occur.
+ {
+ if(size > DATA_BUF_SIZE) size = DATA_BUF_SIZE;
+ ret = recv(sn, buf, size);
+
+ if(ret <= 0) return ret; // check SOCKERR_BUSY & SOCKERR_XXX. For showing the occurrence of SOCKERR_BUSY.
+ size = (uint16_t) ret;
+ sentsize = 0;
+
+ while(size != sentsize)
+ {
+ ret = send(sn, buf+sentsize, size-sentsize);
+ if(ret < 0)
+ {
+ close(sn);
+ return ret;
+ }
+ sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero.
+ }
+ }
+ break;
+ case SOCK_CLOSE_WAIT :
+#ifdef _LOOPBACK_DEBUG_
+ //printf("%d:CloseWait\r\n",sn);
+#endif
+ if((ret = disconnect(sn)) != SOCK_OK) return ret;
+#ifdef _LOOPBACK_DEBUG_
+ printf("%d:Socket Closed\r\n", sn);
+#endif
+ break;
+ case SOCK_INIT :
+#ifdef _LOOPBACK_DEBUG_
+ printf("%d:Listen, TCP server loopback, port [%d]\r\n", sn, port);
+#endif
+ if( (ret = listen(sn)) != SOCK_OK) return ret;
+ break;
+ case SOCK_CLOSED:
+#ifdef _LOOPBACK_DEBUG_
+ //printf("%d:TCP server loopback start\r\n",sn);
+#endif
+ if((ret = socket(sn, Sn_MR_TCP, port, SF_TCP_NODELAY)) != sn) return ret;
+#ifdef _LOOPBACK_DEBUG_
+ //printf("%d:Socket opened\r\n",sn);
+#endif
+ break;
+ default:
+ break;
+ }
+ return 1;
+}
+
+
+int32_t loopback_tcpc(uint8_t sn, uint8_t* buf, uint8_t* destip, uint16_t destport)
+{
+ int32_t ret; // return value for SOCK_ERRORs
+ uint16_t size = 0, sentsize=0;
+
+ // Destination (TCP Server) IP info (will be connected)
+ // >> loopback_tcpc() function parameter
+ // >> Ex)
+ // uint8_t destip[4] = {192, 168, 0, 214};
+ // uint16_t destport = 5000;
+
+ // Port number for TCP client (will be increased)
+ static uint16_t any_port = 50000;
+
+ // Socket Status Transitions
+ // Check the W5500 Socket n status register (Sn_SR, The 'Sn_SR' controlled by Sn_CR command or Packet send/recv status)
+ switch(getSn_SR(sn))
+ {
+ case SOCK_ESTABLISHED :
+ if(getSn_IR(sn) & Sn_IR_CON) // Socket n interrupt register mask; TCP CON interrupt = connection with peer is successful
+ {
+#ifdef _LOOPBACK_DEBUG_
+ printf("%d:Connected to - %d.%d.%d.%d : %d\r\n",sn, destip[0], destip[1], destip[2], destip[3], destport);
+#endif
+ setSn_IR(sn, Sn_IR_CON); // this interrupt should be write the bit cleared to '1'
+ }
+
+ //////////////////////////////////////////////////////////////////////////////////////////////
+ // Data Transaction Parts; Handle the [data receive and send] process
+ //////////////////////////////////////////////////////////////////////////////////////////////
+ if((size = getSn_RX_RSR(sn)) > 0) // Sn_RX_RSR: Socket n Received Size Register, Receiving data length
+ {
+ if(size > DATA_BUF_SIZE) size = DATA_BUF_SIZE; // DATA_BUF_SIZE means user defined buffer size (array)
+ ret = recv(sn, buf, size); // Data Receive process (H/W Rx socket buffer -> User's buffer)
+
+ if(ret <= 0) return ret; // If the received data length <= 0, receive failed and process end
+ size = (uint16_t) ret;
+ sentsize = 0;
+
+ // Data sentsize control
+ while(size != sentsize)
+ {
+ ret = send(sn, buf+sentsize, size-sentsize); // Data send process (User's buffer -> Destination through H/W Tx socket buffer)
+ if(ret < 0) // Send Error occurred (sent data length < 0)
+ {
+ close(sn); // socket close
+ return ret;
+ }
+ sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero.
+ }
+ }
+ //////////////////////////////////////////////////////////////////////////////////////////////
+ break;
+
+ case SOCK_CLOSE_WAIT :
+#ifdef _LOOPBACK_DEBUG_
+ //printf("%d:CloseWait\r\n",sn);
+#endif
+ if((ret=disconnect(sn)) != SOCK_OK) return ret;
+#ifdef _LOOPBACK_DEBUG_
+ printf("%d:Socket Closed\r\n", sn);
+#endif
+ break;
+
+ case SOCK_INIT :
+#ifdef _LOOPBACK_DEBUG_
+ printf("%d:Try to connect to the %d.%d.%d.%d : %d\r\n", sn, destip[0], destip[1], destip[2], destip[3], destport);
+#endif
+ if( (ret = connect(sn, destip, destport)) != SOCK_OK) return ret; // Try to TCP connect to the TCP server (destination)
+ break;
+
+ case SOCK_CLOSED:
+ close(sn);
+ if((ret=socket(sn, Sn_MR_TCP, any_port++, 0x00)) != sn){
+ if(any_port == 0xffff) any_port = 50000;
+ return ret; // TCP socket open with 'any_port' port number
+ }
+#ifdef _LOOPBACK_DEBUG_
+ //printf("%d:TCP client loopback start\r\n",sn);
+ //printf("%d:Socket opened\r\n",sn);
+#endif
+ break;
+ default:
+ break;
+ }
+ return 1;
+}
+
+
+int32_t loopback_udps(uint8_t sn, uint8_t* buf, uint16_t port)
+{
+ int32_t ret;
+ uint16_t size, sentsize;
+ uint8_t destip[4];
+ uint16_t destport;
+
+ switch(getSn_SR(sn))
+ {
+ case SOCK_UDP :
+ if((size = getSn_RX_RSR(sn)) > 0)
+ {
+ if(size > DATA_BUF_SIZE) size = DATA_BUF_SIZE;
+ ret = recvfrom(sn, buf, size, destip, (uint16_t*)&destport);
+ if(ret <= 0)
+ {
+#ifdef _LOOPBACK_DEBUG_
+ printf("%d: recvfrom error. %ld\r\n",sn,ret);
+#endif
+ return ret;
+ }
+ size = (uint16_t) ret;
+ sentsize = 0;
+ while(sentsize != size)
+ {
+ ret = sendto(sn, buf+sentsize, size-sentsize, destip, destport);
+ if(ret < 0)
+ {
+#ifdef _LOOPBACK_DEBUG_
+ printf("%d: sendto error. %ld\r\n",sn,ret);
+#endif
+ return ret;
+ }
+ sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero.
+ }
+ }
+ break;
+ case SOCK_CLOSED:
+#ifdef _LOOPBACK_DEBUG_
+ //printf("%d:UDP loopback start\r\n",sn);
+#endif
+ if((ret = socket(sn, Sn_MR_UDP, port, 0x00)) != sn)
+ return ret;
+#ifdef _LOOPBACK_DEBUG_
+ printf("%d:Opened, UDP loopback, port [%d]\r\n", sn, port);
+#endif
+ break;
+ default :
+ break;
+ }
+ return 1;
+}
+
+
+void register_read(void)
+{
+ int i;
+ printf(" ----register read----\r\n");
+ printf("Address | ");
+ for(i = 0 ; i < 16 ; i++)
+ printf("%02x ",i);
+ printf("\r\n---------------------------------------------------------");
+ for(i = 0 ; i < 0x0090 ; i++)
+ {
+ if(i%16 == 0) printf("\r\n %04x | ", i);
+ printf("%02x ",WIZCHIP_READ(i));
+ }
+ printf("\r\n");
+}
+
+void socket_register_read(uint8_t sn)
+{
+ int i;
+ printf(" ----register read----\r\n");
+ printf("Address | ");
+ for(i = 0 ; i < 16 ; i++)
+ printf("%02x ",i);
+ printf("\r\n---------------------------------------------------------");
+ for(i = 0x400+(sn*(0x100)) ; i < 0x400+(sn*(0x100)+0x35) ; i++)
+ {
+ if(i%16 == 0) printf("\r\n0x%04x | ", i);
+ printf("%02x ",WIZCHIP_READ(i));
+ }
+ printf("\r\n");
+}
+
+#endif
diff --git a/Libraries/ioLibrary_Driver/Application/loopback/loopback.h b/Libraries/ioLibrary_Driver/Application/loopback/loopback.h
new file mode 100644
index 0000000..7e0ecc1
--- /dev/null
+++ b/Libraries/ioLibrary_Driver/Application/loopback/loopback.h
@@ -0,0 +1,34 @@
+#ifndef _LOOPBACK_H_
+#define _LOOPBACK_H_
+
+#include
+
+/* Loopback test debug message printout enable */
+#define _LOOPBACK_DEBUG_
+
+/* DATA_BUF_SIZE define for Loopback example */
+#ifndef DATA_BUF_SIZE
+ #define DATA_BUF_SIZE 2048
+#endif
+
+/************************/
+/* Select LOOPBACK_MODE */
+/************************/
+#define LOOPBACK_MAIN_NOBLOCK 0
+#define LOOPBACK_MODE LOOPBACK_MAIN_NOBLOCK
+
+
+/* TCP server Loopback test example */
+int32_t loopback_tcps(uint8_t sn, uint8_t* buf, uint16_t port);
+
+/* TCP client Loopback test example */
+int32_t loopback_tcpc(uint8_t sn, uint8_t* buf, uint8_t* destip, uint16_t destport);
+
+/* UDP Loopback test example */
+int32_t loopback_udps(uint8_t sn, uint8_t* buf, uint16_t port);
+
+//todo for test
+void register_read(void);
+void socket_register_read(uint8_t sn);
+
+#endif
diff --git a/Libraries/ioLibrary_Driver/Ethernet/Socket_APIs_V3.0.3.chm b/Libraries/ioLibrary_Driver/Ethernet/Socket_APIs_V3.0.3.chm
new file mode 100644
index 0000000..35ed512
Binary files /dev/null and b/Libraries/ioLibrary_Driver/Ethernet/Socket_APIs_V3.0.3.chm differ
diff --git a/Libraries/ioLibrary_Driver/Ethernet/W5100/w5100.c b/Libraries/ioLibrary_Driver/Ethernet/W5100/w5100.c
new file mode 100644
index 0000000..031f499
--- /dev/null
+++ b/Libraries/ioLibrary_Driver/Ethernet/W5100/w5100.c
@@ -0,0 +1,386 @@
+//*****************************************************************************
+//
+//! \file w5100.c
+//! \brief W5100 HAL Interface.
+//! \version 1.0.0
+//! \date 2013/10/21
+//! \par Revision history
+//! <2013/10/21> 1st Release
+//! \author MidnightCow
+//!
+//! Copyright (c) 2013, WIZnet Co., LTD.
+//! All rights reserved.
+//!
+//! Redistribution and use in source and binary forms, with or without
+//! modification, are permitted provided that the following conditions
+//! are met:
+//!
+//! * Redistributions of source code must retain the above copyright
+//! notice, this list of conditions and the following disclaimer.
+//! * Redistributions in binary form must reproduce the above copyright
+//! notice, this list of conditions and the following disclaimer in the
+//! documentation and/or other materials provided with the distribution.
+//! * Neither the name of the nor the names of its
+//! contributors may be used to endorse or promote products derived
+//! from this software without specific prior written permission.
+//!
+//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+//! THE POSSIBILITY OF SUCH DAMAGE.
+//
+//*****************************************************************************
+
+#include "w5100.h"
+
+#if (_WIZCHIP_ == 5100)
+/**
+@brief This function writes the data into W5100 registers.
+*/
+void WIZCHIP_WRITE(uint32_t AddrSel, uint8_t wb )
+{
+ WIZCHIP_CRITICAL_ENTER();
+ WIZCHIP.CS._select();
+
+#if( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_))
+ WIZCHIP.IF.SPI._write_byte(0xF0);
+ WIZCHIP.IF.SPI._write_byte((AddrSel & 0xFF00) >> 8);
+ WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF) >> 0);
+ WIZCHIP.IF.SPI._write_byte(wb); // Data write (write 1byte data)
+#elif ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_DIR_) )
+ //M20150601 : Rename the function for integrating with ioLibrary
+ //WIZCHIP.IF.BUS._write_byte(AddrSel,wb);
+ WIZCHIP.IF.BUS._write_data(AddrSel,wb);
+#elif ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_) )
+
+ //add indirect bus
+ //M20150601 : Rename the function for integrating with ioLibrary
+ //WIZCHIP.IF.BUS._write_byte(IDM_AR0,(AddrSel & 0xFF00) >> 8);
+ //WIZCHIP.IF.BUS._write_byte(IDM_AR1,(AddrSel & 0x00FF));
+ //WIZCHIP.IF.BUS._write_byte(IDM_DR,wb);
+ WIZCHIP.IF.BUS._write_data(IDM_AR0,(AddrSel & 0xFF00) >> 8);
+ WIZCHIP.IF.BUS._write_data(IDM_AR1,(AddrSel & 0x00FF));
+ WIZCHIP.IF.BUS._write_data(IDM_DR,wb);
+#else
+ #error "Unknown _WIZCHIP_IO_MODE_ in W5100. !!!"
+#endif
+
+ WIZCHIP.CS._deselect();
+ WIZCHIP_CRITICAL_EXIT();
+}
+/**
+@brief This function reads the value from W5100 registers.
+*/
+uint8_t WIZCHIP_READ(uint32_t AddrSel)
+{
+ uint8_t ret;
+
+ WIZCHIP_CRITICAL_ENTER();
+ WIZCHIP.CS._select();
+
+#if( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_))
+ WIZCHIP.IF.SPI._write_byte(0x0F);
+ WIZCHIP.IF.SPI._write_byte((AddrSel & 0xFF00) >> 8);
+ WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF) >> 0);
+ ret = WIZCHIP.IF.SPI._read_byte();
+#elif ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_DIR_) )
+ //M20150601 : Rename the function for integrating with ioLibrary
+ //ret = WIZCHIP.IF.BUS._read_byte(AddrSel);
+ ret = WIZCHIP.IF.BUS._read_data(AddrSel);
+#elif ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_) )
+
+ //add indirect bus
+ //M20150601 : Rename the function for integrating with ioLibrary
+ //WIZCHIP.IF.BUS._write_byte(IDM_AR0,(AddrSel & 0xFF00) >> 8);
+ //WIZCHIP.IF.BUS._write_byte(IDM_AR1,(AddrSel & 0x00FF));
+ //ret = WIZCHIP.IF.BUS._read_byte(IDM_DR);
+ WIZCHIP.IF.BUS._write_data(IDM_AR0,(AddrSel & 0xFF00) >> 8);
+ WIZCHIP.IF.BUS._write_data(IDM_AR1,(AddrSel & 0x00FF));
+ ret = WIZCHIP.IF.BUS._read_data(IDM_DR);
+
+#else
+ #error "Unknown _WIZCHIP_IO_MODE_ in W5100. !!!"
+#endif
+
+ WIZCHIP.CS._deselect();
+ WIZCHIP_CRITICAL_EXIT();
+ return ret;
+}
+
+
+/**
+@brief This function writes into W5100 memory(Buffer)
+*/
+void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len)
+{
+ uint16_t i = 0;
+
+ WIZCHIP_CRITICAL_ENTER();
+ WIZCHIP.CS._select(); //M20150601 : Moved here.
+
+#if( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_))
+ for(i = 0; i < len; i++)
+ {
+ //M20160715 : Depricated "M20150601 : Remove _select() to top-side"
+ // CS should be controlled every SPI frames
+ WIZCHIP.CS._select();
+ WIZCHIP.IF.SPI._write_byte(0xF0);
+ WIZCHIP.IF.SPI._write_byte((((uint16_t)(AddrSel+i)) & 0xFF00) >> 8);
+ WIZCHIP.IF.SPI._write_byte((((uint16_t)(AddrSel+i)) & 0x00FF) >> 0);
+ WIZCHIP.IF.SPI._write_byte(pBuf[i]); // Data write (write 1byte data)
+ //M20160715 : Depricated "M20150601 : Remove _select() to top-side"
+ WIZCHIP.CS._deselect();
+ }
+#elif ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_DIR_) )
+ for(i = 0; i < len; i++)
+ //M20150601 : Rename the function for integrating with ioLibrary
+ // WIZCHIP.IF.BUS._write_byte(AddrSel+i,pBuf[i]);
+ WIZCHIP.IF.BUS._write_data(AddrSel+i,pBuf[i]);
+#elif ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_) )
+ //M20150601 : Rename the function for integrating with ioLibrary
+ /*
+ WIZCHIP_WRITE(MR,WIZCHIP_READ(MR) | MR_AI);
+ WIZCHIP.IF.BUS._write_byte(IDM_AR0,(AddrSel & 0xFF00) >> 8);
+ WIZCHIP.IF.BUS._write_byte(IDM_AR1,(AddrSel & 0x00FF));
+ for(i = 0 ; i < len; i++)
+ WIZCHIP.IF.BUS._write_byte(IDM_DR,pBuf[i]);
+ WIZCHIP_WRITE(MR, WIZCHIP_READ(MR) & ~MR_AI);
+ */
+ setMR(getMR()|MR_AI);
+ WIZCHIP.IF.BUS._write_data(IDM_AR0,(AddrSel & 0xFF00) >> 8);
+ WIZCHIP.IF.BUS._write_data(IDM_AR1,(AddrSel & 0x00FF));
+ for(i = 0 ; i < len; i++)
+ WIZCHIP.IF.BUS._write_data(IDM_DR,pBuf[i]);
+ setMR(getMR() & ~MR_AI);
+
+#else
+ #error "Unknown _WIZCHIP_IO_MODE_ in W5100. !!!!"
+#endif
+
+ WIZCHIP.CS._deselect(); //M20150601 : Moved here.
+ WIZCHIP_CRITICAL_EXIT();
+}
+
+/**
+@brief This function reads into W5100 memory(Buffer)
+*/
+
+void WIZCHIP_READ_BUF (uint32_t AddrSel, uint8_t* pBuf, uint16_t len)
+{
+ uint16_t i = 0;
+ WIZCHIP_CRITICAL_ENTER();
+ WIZCHIP.CS._select(); //M20150601 : Moved here.
+
+#if( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_))
+ for(i = 0; i < len; i++)
+ {
+ //M20160715 : Depricated "M20150601 : Remove _select() to top-side"
+ // CS should be controlled every SPI frames
+ WIZCHIP.CS._select();
+ WIZCHIP.IF.SPI._write_byte(0x0F);
+ WIZCHIP.IF.SPI._write_byte((uint16_t)((AddrSel+i) & 0xFF00) >> 8);
+ WIZCHIP.IF.SPI._write_byte((uint16_t)((AddrSel+i) & 0x00FF) >> 0);
+ pBuf[i] = WIZCHIP.IF.SPI._read_byte();
+ //M20160715 : Depricated "M20150601 : Remove _select() to top-side"
+ WIZCHIP.CS._deselect();
+ }
+#elif ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_DIR_) )
+ for(i = 0 ; i < len; i++)
+ //M20150601 : Rename the function for integrating with ioLibrary
+ // pBuf[i] = WIZCHIP.IF.BUS._read_byte(AddrSel+i);
+ pBuf[i] = WIZCHIP.IF.BUS._read_data(AddrSel+i);
+#elif ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_) )
+ //M20150601 : Rename the function for integrating with ioLibrary
+ /*
+ WIZCHIP_WRITE(MR, WIZCHIP_READ(MR) | MR_AI);
+ WIZCHIP.IF.BUS._write_byte(IDM_AR0,(AddrSel & 0xFF00) >> 8);
+ WIZCHIP.IF.BUS._write_byte(IDM_AR1,(AddrSel & 0x00FF));
+ for(i = 0 ; i < len; i++)
+ pBuf[i] = WIZCHIP.IF.BUS._read_byte(IDM_DR);
+ WIZCHIP_WRITE(MR, WIZCHIP_READ(MR) & ~MR_AI);
+ */
+ setMR(getMR() | MR_AI);
+ WIZCHIP.IF.BUS._write_data(IDM_AR0,(AddrSel & 0xFF00) >> 8);
+ WIZCHIP.IF.BUS._write_data(IDM_AR1,(AddrSel & 0x00FF));
+ for(i = 0 ; i < len; i++)
+ pBuf[i] = WIZCHIP.IF.BUS._read_data(IDM_DR);
+ setMR(getMR() & ~MR_AI);
+
+#else
+ #error "Unknown _WIZCHIP_IO_MODE_ in W5100. !!!!"
+#endif
+
+ WIZCHIP.CS._deselect(); //M20150601 : Moved Here.
+ WIZCHIP_CRITICAL_EXIT();
+}
+
+///////////////////////////////////
+// Socket N regsiter IO function //
+///////////////////////////////////
+
+uint16_t getSn_TX_FSR(uint8_t sn)
+{
+ uint16_t val=0,val1=0;
+ do
+ {
+ val1 = WIZCHIP_READ(Sn_TX_FSR(sn));
+ val1 = (val1 << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn),1));
+ if (val1 != 0)
+ {
+ val = WIZCHIP_READ(Sn_TX_FSR(sn));
+ val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn),1));
+ }
+ }while (val != val1);
+ return val;
+}
+
+
+uint16_t getSn_RX_RSR(uint8_t sn)
+{
+ uint16_t val=0,val1=0;
+ do
+ {
+ val1 = WIZCHIP_READ(Sn_RX_RSR(sn));
+ val1 = (val1 << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn),1));
+ if (val1 != 0)
+ {
+ val = WIZCHIP_READ(Sn_RX_RSR(sn));
+ val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn),1));
+ }
+ }while (val != val1);
+ return val;
+}
+
+/////////////////////////////////////
+// Sn_TXBUF & Sn_RXBUF IO function //
+/////////////////////////////////////
+uint32_t getSn_RxBASE(uint8_t sn)
+{
+ int8_t i;
+#if ( _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_DIR_)
+ uint32_t rxbase = _W5100_IO_BASE_ + _WIZCHIP_IO_RXBUF_;
+#else
+ uint32_t rxbase = _WIZCHIP_IO_RXBUF_;
+#endif
+ for(i = 0; i < sn; i++)
+ rxbase += getSn_RxMAX(i);
+
+ return rxbase;
+}
+
+uint32_t getSn_TxBASE(uint8_t sn)
+{
+ int8_t i;
+#if ( _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_DIR_)
+ uint32_t txbase = _W5100_IO_BASE_ + _WIZCHIP_IO_TXBUF_;
+#else
+ uint32_t txbase = _WIZCHIP_IO_TXBUF_;
+#endif
+ for(i = 0; i < sn; i++)
+ txbase += getSn_TxMAX(i);
+ return txbase;
+}
+
+/**
+@brief This function is being called by send() and sendto() function also. for copy the data form application buffer to Transmite buffer of the chip.
+
+This function read the Tx write pointer register and after copy the data in buffer update the Tx write pointer
+register. User should read upper byte first and lower byte later to get proper value.
+And this function is being used for copy the data form application buffer to Transmite
+buffer of the chip. It calculate the actual physical address where one has to write
+the data in transmite buffer. Here also take care of the condition while it exceed
+the Tx memory uper-bound of socket.
+
+*/
+void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint16_t len)
+{
+ uint16_t ptr;
+ uint16_t size;
+ uint16_t dst_mask;
+ uint16_t dst_ptr;
+
+ ptr = getSn_TX_WR(sn);
+
+ dst_mask = ptr & getSn_TxMASK(sn);
+ dst_ptr = getSn_TxBASE(sn) + dst_mask;
+
+ if (dst_mask + len > getSn_TxMAX(sn))
+ {
+ size = getSn_TxMAX(sn) - dst_mask;
+ WIZCHIP_WRITE_BUF(dst_ptr, wizdata, size);
+ wizdata += size;
+ size = len - size;
+ dst_ptr = getSn_TxBASE(sn);
+ WIZCHIP_WRITE_BUF(dst_ptr, wizdata, size);
+ }
+ else
+ {
+ WIZCHIP_WRITE_BUF(dst_ptr, wizdata, len);
+ }
+
+ ptr += len;
+
+ setSn_TX_WR(sn, ptr);
+}
+
+
+/**
+@brief This function is being called by recv() also. This function is being used for copy the data form Receive buffer of the chip to application buffer.
+
+This function read the Rx read pointer register
+and after copy the data from receive buffer update the Rx write pointer register.
+User should read upper byte first and lower byte later to get proper value.
+It calculate the actual physical address where one has to read
+the data from Receive buffer. Here also take care of the condition while it exceed
+the Rx memory uper-bound of socket.
+*/
+void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len)
+{
+ uint16_t ptr;
+ uint16_t size;
+ uint16_t src_mask;
+ uint16_t src_ptr;
+
+ ptr = getSn_RX_RD(sn);
+
+ src_mask = (uint32_t)ptr & getSn_RxMASK(sn);
+ src_ptr = (getSn_RxBASE(sn) + src_mask);
+
+
+ if( (src_mask + len) > getSn_RxMAX(sn) )
+ {
+ size = getSn_RxMAX(sn) - src_mask;
+ WIZCHIP_READ_BUF((uint32_t)src_ptr, (uint8_t*)wizdata, size);
+ wizdata += size;
+ size = len - size;
+ src_ptr = getSn_RxBASE(sn);
+ WIZCHIP_READ_BUF(src_ptr, (uint8_t*)wizdata, size);
+ }
+ else
+ {
+ WIZCHIP_READ_BUF(src_ptr, (uint8_t*)wizdata, len);
+ }
+
+ ptr += len;
+
+ setSn_RX_RD(sn, ptr);
+}
+
+void wiz_recv_ignore(uint8_t sn, uint16_t len)
+{
+ uint16_t ptr;
+
+ ptr = getSn_RX_RD(sn);
+
+ ptr += len;
+ setSn_RX_RD(sn,ptr);
+}
+
+#endif
diff --git a/Libraries/ioLibrary_Driver/Ethernet/W5100/w5100.h b/Libraries/ioLibrary_Driver/Ethernet/W5100/w5100.h
new file mode 100644
index 0000000..747d27c
--- /dev/null
+++ b/Libraries/ioLibrary_Driver/Ethernet/W5100/w5100.h
@@ -0,0 +1,1856 @@
+//* ****************************************************************************
+//! \file w5100.h
+//! \brief W5100 HAL Header File.
+//! \version 1.0.0
+//! \date 2013/10/21
+//! \par Revision history
+//! <2013/10/21> 1st Release
+//! \author MidnightCow
+//! \copyright
+//!
+//! Copyright (c) 2013, WIZnet Co., LTD.
+//! All rights reserved.
+//!
+//! Redistribution and use in source and binary forms, with or without
+//! modification, are permitted provided that the following conditions
+//! are met:
+//!
+//! * Redistributions of source code must retain the above copyright
+//! notice, this list of conditions and the following disclaimer.
+//! * Redistributions in binary form must reproduce the above copyright
+//! notice, this list of conditions and the following disclaimer in the
+//! documentation and/or other materials provided with the distribution.
+//! * Neither the name of the nor the names of its
+//! contributors may be used to endorse or promote products derived
+//! from this software without specific prior written permission.
+//!
+//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+//! THE POSSIBILITY OF SUCH DAMAGE.
+//
+//*****************************************************************************
+
+#ifndef _W5100_H_
+#define _W5100_H_
+#include
+#include "wizchip_conf.h"
+
+/// \cond DOXY_APPLY_CODE
+#if (_WIZCHIP_ == 5100)
+/// \endcond
+
+#define _WIZCHIP_SN_BASE_ (0x0400)
+#define _WIZCHIP_SN_SIZE_ (0x0100)
+#define _WIZCHIP_IO_TXBUF_ (0x4000) /* Internal Tx buffer address of the iinchip */
+#define _WIZCHIP_IO_RXBUF_ (0x6000) /* Internal Rx buffer address of the iinchip */
+
+
+#define WIZCHIP_CREG_BLOCK 0x00 ///< Common register block
+#define WIZCHIP_SREG_BLOCK(N) (_WIZCHIP_SN_BASE_+ _WIZCHIP_SN_SIZE_*N) ///< Socket N register block
+
+#define WIZCHIP_OFFSET_INC(ADDR, N) (ADDR + N) ///< Increase offset address
+
+#if (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_DIR_)
+ #define _W5100_IO_BASE_ _WIZCHIP_IO_BASE_
+#elif (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_)
+ #define IDM_OR ((_WIZCHIP_IO_BASE + 0x0000))
+ #define IDM_AR0 ((_WIZCHIP_IO_BASE_ + 0x0001))
+ #define IDM_AR1 ((_WIZCHIP_IO_BASE_ + 0x0002))
+ #define IDM_DR ((_WIZCHIP_IO_BASE_ + 0x0003))
+ #define _W5100_IO_BASE_ 0x0000
+#elif (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_)
+ #define _W5100_IO_BASE_ 0x0000
+#endif
+
+///////////////////////////////////////
+// Definition For Legacy Chip Driver //
+///////////////////////////////////////
+#define IINCHIP_READ(ADDR) WIZCHIP_READ(ADDR) ///< The defined for legacy chip driver
+#define IINCHIP_WRITE(ADDR,VAL) WIZCHIP_WRITE(ADDR,VAL) ///< The defined for legacy chip driver
+#define IINCHIP_READ_BUF(ADDR,BUF,LEN) WIZCHIP_READ_BUF(ADDR,BUF,LEN) ///< The defined for legacy chip driver
+#define IINCHIP_WRITE_BUF(ADDR,BUF,LEN) WIZCHIP_WRITE(ADDR,BUF,LEN) ///< The defined for legacy chip driver
+
+
+//----------- defgroup --------------------------------
+
+/**
+ * @defgroup W5100 W5100
+ * @brief WHIZCHIP register defines and I/O functions of @b W5100.
+ *
+ * - @ref WIZCHIP_register_W5100 : @ref Common_register_group_W5100 and @ref Socket_register_group_W5100
+ * - @ref WIZCHIP_IO_Functions_W5100 : @ref Basic_IO_function_W5100, @ref Common_register_access_function_W5100 and @ref Socket_register_group_W5100
+ */
+
+ /**
+ * @defgroup WIZCHIP_register_W5100 WIZCHIP register
+ * @ingroup W5100
+ * @brief WIZCHIP register defines register group of W5100 .
+ *
+ * - \ref Common_register_group_W5100 : Common register group W5100
+ * - \ref Socket_register_group_W5100 : \c SOCKET n register group W5100
+ */
+
+
+/**
+ * @defgroup WIZCHIP_IO_Functions_W5100 WIZCHIP I/O functions
+ * @ingroup W5100
+ * @brief This supports the basic I/O functions for \ref WIZCHIP_register_W5100.
+ *
+ * - Basic I/O function \n
+ * WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF() \n\n
+ *
+ * - \ref Common_register_group_W5100 access functions \n
+ * -# @b Mode \n
+ * getMR(), setMR()
+ * -# @b Interrupt \n
+ * getIR(), setIR(), getIMR(), setIMR(),
+ * -# Network Information \n
+ * getSHAR(), setSHAR(), getGAR(), setGAR(), getSUBR(), setSUBR(), getSIPR(), setSIPR()
+ * -# @b Retransmission \n
+ * getRCR(), setRCR(), getRTR(), setRTR()
+ * -# @b PPPoE \n
+ * getPTIMER(), setPTIMER(), getPMAGIC(), getPMAGIC()
+ *
+ * - \ref Socket_register_group_W5100 access functions \n
+ * -# SOCKET control \n
+ * getSn_MR(), setSn_MR(), getSn_CR(), setSn_CR(), getSn_IR(), setSn_IR()
+ * -# SOCKET information \n
+ * getSn_SR(), getSn_DHAR(), setSn_DHAR(), getSn_PORT(), setSn_PORT(), getSn_DIPR(), setSn_DIPR(), getSn_DPORT(), setSn_DPORT()
+ * getSn_MSSR(), setSn_MSSR()
+ * -# SOCKET communication \n
+ * getSn_RXMEM_SIZE(), setSn_RXMEM_SIZE(), getSn_TXMEM_SIZE(), setSn_TXMEM_SIZE() \n
+ * getSn_TX_RD(), getSn_TX_WR(), setSn_TX_WR() \n
+ * getSn_RX_RD(), setSn_RX_RD(), getSn_RX_WR() \n
+ * getSn_TX_FSR(), getSn_RX_RSR()
+ * -# IP header field \n
+ * getSn_FRAG(), setSn_FRAG(), getSn_TOS(), setSn_TOS() \n
+ * getSn_TTL(), setSn_TTL()
+ */
+
+/**
+ * @defgroup Common_register_group_W5100 Common register
+ * @ingroup WIZCHIP_register_W5100
+ * @brief Common register group\n
+ * It set the basic for the networking\n
+ * It set the configuration such as interrupt, network information, ICMP, etc.
+ * @details
+ * @sa MR : Mode register.
+ * @sa GAR, SUBR, SHAR, SIPR
+ * @sa IR, Sn_IR, _IMR_ : Interrupt.
+ * @sa _RTR_, _RCR_ : Data retransmission.
+ * @sa PTIMER, PMAGIC : PPPoE.
+ */
+
+
+ /**
+ * @defgroup Socket_register_group_W5100 Socket register
+ * @ingroup WIZCHIP_register_W5100
+ * @brief Socket register group\n
+ * Socket register configures and control SOCKETn which is necessary to data communication.
+ * @details
+ * @sa Sn_MR, Sn_CR, Sn_IR : SOCKETn Control
+ * @sa Sn_SR, Sn_PORT, Sn_DHAR, Sn_DIPR, Sn_DPORT : SOCKETn Information
+ * @sa Sn_MSSR, Sn_TOS, Sn_TTL, Sn_FRAG : Internet protocol.
+ * @sa Sn_RXMEM_SIZE, Sn_TXMEM_SIZE, Sn_TX_FSR, Sn_TX_RD, Sn_TX_WR, Sn_RX_RSR, Sn_RX_RD, Sn_RX_WR : Data communication
+ */
+
+ /**
+ * @defgroup Basic_IO_function_W5100 Basic I/O function
+ * @ingroup WIZCHIP_IO_Functions_W5100
+ * @brief These are basic input/output functions to read values from register or write values to register.
+ */
+
+/**
+ * @defgroup Common_register_access_function_W5100 Common register access functions
+ * @ingroup WIZCHIP_IO_Functions_W5100
+ * @brief These are functions to access common registers.
+ */
+
+/**
+ * @defgroup Socket_register_access_function_W5100 Socket register access functions
+ * @ingroup WIZCHIP_IO_Functions_W5100
+ * @brief These are functions to access socket registers.
+ */
+
+ //-----------------------------------------------------------------------------------
+
+//----------------------------- W5100 Common Registers IOMAP -----------------------------
+/**
+ * @ingroup Common_register_group_W5100
+ * @brief Mode Register address(R/W)\n
+ * \ref MR is used for S/W reset, ping block mode, PPPoE mode and etc.
+ * @details Each bit of \ref MR defined as follows.
+ *
+ *
7
6
5
4
3
2
1
0
+ *
RST
Reserved
WOL
PB
PPPoE
Reserved
AI
IND
+ *
+ * - \ref MR_RST : Reset
+ * - \ref MR_PB : Ping block
+ * - \ref MR_PPPOE : PPPoE mode
+ * - \ref MR_AI : Address Auto-Increment in Indirect Bus Interface
+ * - \ref MR_IND : Indirect Bus Interface mode
+ */
+#if _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_
+ #define MR (_WIZCHIP_IO_BASE_ + (0x0000)) // Mode
+#else
+ #define MR (_W5100_IO_BASE_ + (0x0000)) // Mode
+#endif
+
+/**
+ * @ingroup Common_register_group_W5100
+ * @brief Gateway IP Register address(R/W)
+ * @details \ref GAR configures the default gateway address.
+ */
+#define GAR (_W5100_IO_BASE_ + (0x0001)) // GW Address
+
+/**
+ * @ingroup Common_register_group_W5100
+ * @brief Subnet mask Register address(R/W)
+ * @details \ref SUBR configures the subnet mask address.
+ */
+#define SUBR (_W5100_IO_BASE_ + (0x0005)) // SN Mask Address
+
+/**
+ * @ingroup Common_register_group_W5100
+ * @brief Source MAC Register address(R/W)
+ * @details \ref SHAR configures the source hardware address.
+ */
+#define SHAR (_W5100_IO_BASE_ + (0x0009)) // Source Hardware Address
+
+/**
+ * @ingroup Common_register_group_W5100
+ * @brief Source IP Register address(R/W)
+ * @details \ref SIPR configures the source IP address.
+ */
+#define SIPR (_W5100_IO_BASE_ + (0x000F)) // Source IP Address
+
+// Reserved (_W5100_IO_BASE_ + (0x0013))
+// Reserved (_W5100_IO_BASE_ + (0x0014))
+
+/**
+ * @ingroup Common_register_group_W5100
+ * @brief Interrupt Register(R/W)
+ * @details \ref IR indicates the interrupt status. Each bit of \ref IR will be still until the bit will be written to by the host.
+ * If \ref IR is not equal to x00 INTn PIN is asserted to low until it is x00\n\n
+ * Each bit of \ref IR defined as follows.
+ *
+ *
7
6
5
4
3
2
1
0
+ *
CONFLICT
UNREACH
PPPoE
Reserved
S3_INT
S2_INT
S1_INT
S0_INT
+ *
+ * - \ref IR_CONFLICT : IP conflict
+ * - \ref IR_UNREACH : Destination unreachable
+ * - \ref IR_PPPoE : PPPoE connection close
+ * - \ref IR_SOCK(3) : SOCKET 3 Interrupt
+ * - \ref IR_SOCK(2) : SOCKET 2 Interrupt
+ * - \ref IR_SOCK(1) : SOCKET 1 Interrupt
+ * - \ref IR_SOCK(0) : SOCKET 0 Interrupt
+ */
+#define IR (_W5100_IO_BASE_ + (0x0015)) // Interrupt
+
+/**
+ * @ingroup Common_register_group_W5100
+ * @brief Socket Interrupt Mask Register(R/W)
+ * @details Each bit of \ref _IMR_ corresponds to each bit of \ref IR.
+ * When a bit of \ref _IMR_ is and the corresponding bit of \ref IR is set, Interrupt will be issued.
+ */
+#define _IMR_ (_W5100_IO_BASE_ + (0x0016)) // Socket Interrupt Mask
+
+/**
+ * @ingroup Common_register_group_W5100
+ * @brief Timeout register address( 1 is 100us )(R/W)
+ * @details \ref _RTR_ configures the retransmission timeout period. The unit of timeout period is 100us and the default of \ref _RTR_ is x07D0or 000
+ * And so the default timeout period is 200ms(100us X 2000). During the time configured by \ref _RTR_, W5100 waits for the peer response
+ * to the packet that is transmitted by \ref Sn_CR (CONNECT, DISCON, CLOSE, SEND, SEND_MAC, SEND_KEEP command).
+ * If the peer does not respond within the \ref _RTR_ time, W5100 retransmits the packet or issues timeout.
+ */
+#define _RTR_ (_W5100_IO_BASE_ + (0x0017)) // Retry Time
+
+/**
+ * @ingroup Common_register_group_W5100
+ * @brief Retry count register(R/W)
+ * @details \ref _RCR_ configures the number of time of retransmission.
+ * When retransmission occurs as many as ref _RCR_+1 Timeout interrupt is issued (\ref Sn_IR_TIMEOUT = '1').
+ */
+#define _RCR_ (_W5100_IO_BASE_ + (0x0019)) // Retry Count
+#define RMSR (_W5100_IO_BASE_ + (0x001A)) // Receicve Memory Size
+#define TMSR (_W5100_IO_BASE_ + (0x001B)) // Trnasmit Memory Size
+
+
+/**
+ * @ingroup Common_register_group_W5100
+ * @brief PPP LCP Request Timer register in PPPoE mode(R)
+ * @details \ref PATR notifies authentication method that has been agreed at the connection with
+ * PPPoE Server. W5100 supports two types of Authentication method - PAP and CHAP.
+ */
+#define PATR (_W5100_IO_BASE_ + (0x001C))
+
+
+/**
+ * @ingroup Common_register_group_W5100
+ * @brief PPP LCP Request Timer register in PPPoE mode(R)
+ * @details \ref PTIMER configures the time for sending LCP echo request. The unit of time is 25ms.
+ */
+#define PTIMER (_W5100_IO_BASE_ + (0x0028)) // PPP LCP RequestTimer
+
+/**
+ * @ingroup Common_register_group_W5100
+ * @brief PPP LCP Magic number register in PPPoE mode(R)
+ * @details \ref PMAGIC configures the 4bytes magic number to be used in LCP negotiation.
+ */
+#define PMAGIC (_W5100_IO_BASE_ + (0x0029)) // PPP LCP Magic number
+
+#define UIPR0 (_W5100_IO_BASE_ + (0x002A))
+#define UPORT0 (_W5100_IO_BASE + (0x002E))
+
+
+
+//----------------------------- W5100 Socket Registers -----------------------------
+
+//--------------------------- For Backward Compatibility ---------------------------
+
+/**
+ * @ingroup Socket_register_group_W5100
+ * @brief socket Mode register(R/W)
+ * @details \ref Sn_MR configures the option or protocol type of Socket n.\n\n
+ * Each bit of \ref Sn_MR defined as the following.
+ *
+ *
7
6
5
4
3
2
1
0
+ *
MULTI
MF
ND/MC
Reserved
Protocol[3]
Protocol[2]
Protocol[1]
Protocol[0]
+ *
+ * - \ref Sn_MR_MULTI : Support UDP Multicasting
+ * - \ref Sn_MR_MF : Support MACRAW
+ * - \ref Sn_MR_ND : No Delayed Ack(TCP) flag
+ * - \ref Sn_MR_MC : IGMP version used in UDP mulitcasting
+ * - Protocol
+ *
+ *
Protocol[3]
Protocol[2]
Protocol[1]
Protocol[0]
@b Meaning
+ *
0
0
0
0
Closed
+ *
0
0
0
1
TCP
+ *
0
0
1
0
UDP
+ *
0
1
0
0
MACRAW
+ *
+ * - In case of Socket 0
+ *
+ *
Protocol[3]
Protocol[2]
Protocol[1]
Protocol[0]
@b Meaning
+ *
0
1
0
0
MACRAW
+ *
0
1
0
1
PPPoE
+ *
+ * - \ref Sn_MR_MACRAW : MAC LAYER RAW SOCK \n
+ * - \ref Sn_MR_UDP : UDP
+ * - \ref Sn_MR_TCP : TCP
+ * - \ref Sn_MR_CLOSE : Unused socket
+ * @note MACRAW mode should be only used in Socket 0.
+ */
+#define Sn_MR(sn) (_W5100_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0000)) // socket Mode register
+
+/**
+ * @ingroup Socket_register_group_W5100
+ * @brief Socket command register(R/W)
+ * @details This is used to set the command for Socket n such as OPEN, CLOSE, CONNECT, LISTEN, SEND, and RECEIVE.\n
+ * After W5100 accepts the command, the \ref Sn_CR register is automatically cleared to 0x00.
+ * Even though \ref Sn_CR is cleared to 0x00, the command is still being processed.\n
+ * To check whether the command is completed or not, please check the \ref Sn_IR or \ref Sn_SR.
+ * - \ref Sn_CR_OPEN : Initialize or open socket.
+ * - \ref Sn_CR_LISTEN : Wait connection request in TCP mode(Server mode)
+ * - \ref Sn_CR_CONNECT : Send connection request in TCP mode(Client mode)
+ * - \ref Sn_CR_DISCON : Send closing request in TCP mode.
+ * - \ref Sn_CR_CLOSE : Close socket.
+ * - \ref Sn_CR_SEND : Update TX buffer pointer and send data.
+ * - \ref Sn_CR_SEND_MAC : Send data with MAC address, so without ARP process.
+ * - \ref Sn_CR_SEND_KEEP : Send keep alive message.
+ * - \ref Sn_CR_RECV : Update RX buffer pointer and receive data.
+ * - In case of S0_MR(P3:P0) = S0_MR_PPPoE
+ *
+ *
Value
Symbol
Description
+ *
0x23
PCON
PPPoE connection begins by transmitting PPPoE discovery packet
+ *
0x24
PDISCON
Closes PPPoE connection
+ *
0x25
PCR
In each phase, it transmits REQ message.
+ *
0x26
PCN
In each phase, it transmits NAK message.
+ *
0x27
PCJ
In each phase, it transmits REJECT message.
+ *
+ */
+#define Sn_CR(sn) (_W5100_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0001)) // channel Sn_CR register
+
+/**
+ * @ingroup Socket_register_group_W5100
+ * @brief Socket interrupt register(R)
+ * @details \ref Sn_IR indicates the status of Socket Interrupt such as establishment, termination, receiving data, timeout).\n
+ * When an interrupt occurs and the corresponding bit \ref IR_SOCK(N) in \ref _IMR_ are set, \ref IR_SOCK(N) in \ref IR becomes '1'.\n
+ * In order to clear the \ref Sn_IR bit, the host should write the bit to \n
+ *
+ *
7
6
5
4
3
2
1
0
+ *
PRECV
PFAIL
PNEXT
SEND_OK
TIMEOUT
RECV
DISCON
CON
+ *
+ * - \ref Sn_IR_PRECV : PPP Receive Interrupt
+ * - \ref Sn_IR_PFAIL : PPP Fail Interrupt
+ * - \ref Sn_IR_PNEXT : PPP Next Phase Interrupt
+ * - \ref Sn_IR_SENDOK : SEND_OK Interrupt
+ * - \ref Sn_IR_TIMEOUT : TIMEOUT Interrupt
+ * - \ref Sn_IR_RECV : RECV Interrupt
+ * - \ref Sn_IR_DISCON : DISCON Interrupt
+ * - \ref Sn_IR_CON : CON Interrupt
+ */
+#define Sn_IR(sn) (_W5100_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0002)) // channel interrupt register
+
+/**
+ * @ingroup Socket_register_group_W5100
+ * @brief Socket status register(R)
+ * @details \ref Sn_SR indicates the status of Socket n.\n
+ * The status of Socket n is changed by \ref Sn_CR or some special control packet as SYN, FIN packet in TCP.
+ * @par Normal status
+ * - \ref SOCK_CLOSED : Closed
+ * - \ref SOCK_INIT : Initiate state
+ * - \ref SOCK_LISTEN : Listen state
+ * - \ref SOCK_ESTABLISHED : Success to connect
+ * - \ref SOCK_CLOSE_WAIT : Closing state
+ * - \ref SOCK_UDP : UDP socket
+ * - \ref SOCK_MACRAW : MAC raw mode socket
+ *@par Temporary status during changing the status of Socket n.
+ * - \ref SOCK_SYNSENT : This indicates Socket n sent the connect-request packet (SYN packet) to a peer.
+ * - \ref SOCK_SYNRECV : It indicates Socket n successfully received the connect-request packet (SYN packet) from a peer.
+ * - \ref SOCK_FIN_WAIT : Connection state
+ * - \ref SOCK_CLOSING : Closing state
+ * - \ref SOCK_TIME_WAIT : Closing state
+ * - \ref SOCK_LAST_ACK : Closing state
+ */
+#define Sn_SR(sn) (_W5100_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0003)) // channel status register
+
+/**
+ * @ingroup Socket_register_group_W5100
+ * @brief source port register(R/W)
+ * @details \ref Sn_PORT configures the source port number of Socket n.
+ * It is valid when Socket n is used in TCP/UDP mode. It should be set before OPEN command is ordered.
+*/
+#define Sn_PORT(sn) (_W5100_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0004)) // source port register
+
+/**
+ * @ingroup Socket_register_group_W5100
+ * @brief Peer MAC register address(R/W)
+ * @details \ref Sn_DHAR configures the destination hardware address of Socket n when using SEND_MAC command in UDP mode or
+ * it indicates that it is acquired in ARP-process by CONNECT/SEND command.
+ */
+#define Sn_DHAR(sn) (_W5100_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0006)) // Peer MAC register address
+
+/**
+ * @ingroup Socket_register_group_W5100
+ * @brief Peer IP register address(R/W)
+ * @details \ref Sn_DIPR configures or indicates the destination IP address of Socket n. It is valid when Socket n is used in TCP/UDP mode.
+ * In TCP client mode, it configures an IP address of TCP server before CONNECT command.
+ * In TCP server mode, it indicates an IP address of TCP client after successfully establishing connection.
+ * In UDP mode, it configures an IP address of peer to be received the UDP packet by SEND or SEND_MAC command.
+ */
+#define Sn_DIPR(sn) (_W5100_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x000C)) // Peer IP register address
+
+/**
+ * @ingroup Socket_register_group_W5100
+ * @brief Peer port register address(R/W)
+ * @details \ref Sn_DPORT configures or indicates the destination port number of Socket n. It is valid when Socket n is used in TCP/UDP mode.
+ * In TCP clientmode, it configures the listen port number of TCP server before CONNECT command.
+ * In TCP Servermode, it indicates the port number of TCP client after successfully establishing connection.
+ * In UDP mode, it configures the port number of peer to be transmitted the UDP packet by SEND/SEND_MAC command.
+ */
+#define Sn_DPORT(sn) (_W5100_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0010)) // Peer port register address
+
+/**
+ * @ingroup Socket_register_group_W5100
+ * @brief Maximum Segment Size(Sn_MSSR0) register address(R/W)
+ * @details \ref Sn_MSSR configures or indicates the MTU(Maximum Transfer Unit) of Socket n.
+ */
+#define Sn_MSSR(sn) (_W5100_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0012)) // Maximum Segment Size(Sn_MSSR0) register address
+
+/**
+ * @ingroup Socket_register_group_W5100
+ * @brief IP Protocol(PROTO) Register(R/W)
+ * @details \ref Sn_PROTO that sets the protocol number field of the IP header at the IP layer. It is
+ * valid only in IPRAW mode, and ignored in other modes.
+ */
+#define Sn_PROTO(sn) (_W5100_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0014)) // Protocol of IP Header field register in IP raw mode
+
+/**
+ * @ingroup Socket_register_group_W5100
+ * @brief IP Type of Service(TOS) Register(R/W)
+ * @details \ref Sn_TOS configures the TOS(Type Of Service field in IP Header) of Socket n.
+ * It is set before OPEN command.
+ */
+#define Sn_TOS(sn) (_W5100_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + 0x0015) // IP Type of Service(TOS) Register
+
+/**
+ * @ingroup Socket_register_group_W5100
+ * @brief IP Time to live(TTL) Register(R/W)
+ * @details \ref Sn_TTL configures the TTL(Time To Live field in IP header) of Socket n.
+ * It is set before OPEN command.
+ */
+#define Sn_TTL(sn) (_W5100_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0016)) // IP Time to live(TTL) Register
+
+// Reserved (_W5100_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0017))
+// Reserved (_W5100_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0018))
+// Reserved (_W5100_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0019))
+// Reserved (_W5100_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x001A))
+// Reserved (_W5100_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x001B))
+// Reserved (_W5100_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x001C))
+// Reserved (_W5100_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x001D))
+
+/**
+ * @ingroup Socket_register_group_W5100
+ * @brief Transmit free memory size register(R)
+ * @details \ref Sn_TX_FSR indicates the free size of Socket n TX Buffer Block. It is initialized to the configured size by \ref Sn_TXMEM_SIZE.
+ * Data bigger than \ref Sn_TX_FSR should not be saved in the Socket n TX Buffer because the bigger data overwrites the previous saved data not yet sent.
+ * Therefore, check before saving the data to the Socket n TX Buffer, and if data is equal or smaller than its checked size,
+ * transmit the data with SEND/SEND_MAC command after saving the data in Socket n TX buffer. But, if data is bigger than its checked size,
+ * transmit the data after dividing into the checked size and saving in the Socket n TX buffer.
+ */
+#define Sn_TX_FSR(sn) (_W5100_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0020)) // Transmit free memory size register
+
+/**
+ * @ingroup Socket_register_group_W5100
+ * @brief Transmit memory read pointer register address(R)
+ * @details \ref Sn_TX_RD is initialized by OPEN command. However, if Sn_MR(P[3:0]) is TCP mode(001), it is re-initialized while connecting with TCP.
+ * After its initialization, it is auto-increased by SEND command.
+ * SEND command transmits the saved data from the current \ref Sn_TX_RD to the \ref Sn_TX_WR in the Socket n TX Buffer.
+ * After transmitting the saved data, the SEND command increases the \ref Sn_TX_RD as same as the \ref Sn_TX_WR.
+ * If its increment value exceeds the maximum value 0xFFFF, (greater than 0x10000 and the carry bit occurs),
+ * then the carry bit is ignored and will automatically update with the lower 16bits value.
+ */
+#define Sn_TX_RD(sn) (_W5100_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0022)) // Transmit memory read pointer register address
+
+/**
+ * @ingroup Socket_register_group_W5100
+ * @brief Transmit memory write pointer register address(R/W)
+ * @details \ref Sn_TX_WR is initialized by OPEN command. However, if Sn_MR(P[3:0]) is TCP mode(001), it is re-initialized while connecting with TCP.\n
+ * It should be read or be updated like as follows.\n
+ * 1. Read the starting address for saving the transmitting data.\n
+ * 2. Save the transmitting data from the starting address of Socket n TX buffer.\n
+ * 3. After saving the transmitting data, update \ref Sn_TX_WR to the increased value as many as transmitting data size.
+ * If the increment value exceeds the maximum value 0xFFFF(greater than 0x10000 and the carry bit occurs),
+ * then the carry bit is ignored and will automatically update with the lower 16bits value.\n
+ * 4. Transmit the saved data in Socket n TX Buffer by using SEND/SEND command
+ */
+#define Sn_TX_WR(sn) (_W5100_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0024)) // Transmit memory write pointer register address
+
+/**
+ * @ingroup Socket_register_group_W5100
+ * @brief Received data size register(R)
+ * @details \ref Sn_RX_RSR indicates the data size received and saved in Socket n RX Buffer.
+ * \ref Sn_RX_RSR does not exceed the \ref Sn_RXMEM_SIZE and is calculated as the difference between
+ * Socket n RX Write Pointer (\ref Sn_RX_WR)and Socket n RX Read Pointer (\ref Sn_RX_RD)
+ */
+#define Sn_RX_RSR(sn) (_W5100_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0026)) // Received data size register
+
+/**
+ * @ingroup Socket_register_group_W5100
+ * @brief Read point of Receive memory(R/W)
+ * @details \ref Sn_RX_RD is initialized by OPEN command. Make sure to be read or updated as follows.\n
+ * 1. Read the starting save address of the received data.\n
+ * 2. Read data from the starting address of Socket n RX Buffer.\n
+ * 3. After reading the received data, Update \ref Sn_RX_RD to the increased value as many as the reading size.
+ * If the increment value exceeds the maximum value 0xFFFF, that is, is greater than 0x10000 and the carry bit occurs,
+ * update with the lower 16bits value ignored the carry bit.\n
+ * 4. Order RECV command is for notifying the updated \ref Sn_RX_RD to W5100.
+ */
+#define Sn_RX_RD(sn) (_W5100_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0028)) // Read point of Receive memory
+
+/**
+ * @ingroup Socket_register_group_W5100
+ * @brief Write point of Receive memory(R)
+ * @details \ref Sn_RX_WR is initialized by OPEN command and it is auto-increased by the data reception.
+ * If the increased value exceeds the maximum value 0xFFFF, (greater than 0x10000 and the carry bit occurs),
+ * then the carry bit is ignored and will automatically update with the lower 16bits value.
+ */
+#define Sn_RX_WR(sn) (_W5100_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x002A)) // Write point of Receive memory
+
+
+//----------------------------- W5100 Register values -----------------------------
+
+/* MODE register values */
+/**
+ * @brief Reset
+ * @details If this bit is All internal registers will be initialized. It will be automatically cleared as after S/W reset.
+ */
+#define MR_RST 0x80 ///< reset
+
+
+/**
+ * @brief Ping block
+ * @details 0 : Disable Ping block\n
+ * 1 : Enable Ping block\n
+ * If the bit is it blocks the response to a ping request.
+ */
+#define MR_PB 0x10 ///< ping block
+
+/**
+ * @brief Enable PPPoE
+ * @details 0 : DisablePPPoE mode\n
+ * 1 : EnablePPPoE mode\n
+ * If you use ADSL, this bit should be '1'.
+ */
+#define MR_PPPOE 0x08 ///< enable pppoe
+
+/**
+ * @brief Address Auto-Increment in Indirect Bus Interface
+ * @details 0 : Disable auto-increment \n
+ * 1 : Enable auto-incremente \n
+ * At the Indirect Bus Interface mode, if this bit is set as ��1��, the address will
+ * be automatically increased by 1 whenever read and write are performed.
+ */
+#define MR_AI 0x02 ///< auto-increment in indirect mode
+
+/**
+ * @brief Indirect Bus Interface mode
+ * @details 0 : Disable Indirect bus Interface mode \n
+ * 1 : Enable Indirect bus Interface mode \n
+ * If this bit is set as ��1��, Indirect Bus Interface mode is set.
+ */
+#define MR_IND 0x01 ///< enable indirect mode
+
+/* IR register values */
+/**
+ * @brief Check IP conflict.
+ * @details Bit is set as when own source IP address is same with the sender IP address in the received ARP request.
+ */
+#define IR_CONFLICT 0x80 ///< check ip confict
+
+/**
+ * @brief Get the destination unreachable message in UDP sending.
+ * @details When receiving the ICMP (Destination port unreachable) packet, this bit is set as
+ * When this bit is Destination Information such as IP address and Port number may be checked with the corresponding @ref UIPR & @ref UPORTR.
+ */
+#define IR_UNREACH 0x40 ///< check destination unreachable
+
+/**
+ * @brief Get the PPPoE close message.
+ * @details When PPPoE is disconnected during PPPoE mode, this bit is set.
+ */
+#define IR_PPPoE 0x20 ///< get the PPPoE close message
+
+#define IR_SOCK(sn) (0x01 << sn) ///< check socket interrupt
+
+
+// Sn_MR values
+/* Sn_MR Default values */
+/**
+ * @brief Unused socket
+ * @details This configures the protocol mode of Socket n.
+ */
+#define Sn_MR_CLOSE 0x00 ///< unused socket
+
+/**
+ * @brief TCP
+ * @details This configures the protocol mode of Socket n.
+ */
+#define Sn_MR_TCP 0x01 ///< TCP
+
+/**
+ * @brief UDP
+ * @details This configures the protocol mode of Socket n.
+ */
+#define Sn_MR_UDP 0x02 ///< UDP
+#define Sn_MR_IPRAW 0x03 ///< IP LAYER RAW SOCK
+
+/**
+ * @brief MAC LAYER RAW SOCK
+ * @details This configures the protocol mode of Socket n.
+ * @note MACRAW mode should be only used in Socket 0.
+ */
+#define Sn_MR_MACRAW 0x04 ///< MAC LAYER RAW SOCK
+
+/**
+ * @brief PPPoE
+ * @details This configures the protocol mode of Socket n.
+ * @note PPPoE mode should be only used in Socket 0.
+ */
+#define Sn_MR_PPPoE 0x05 ///< PPPoE
+
+/**
+ * @brief No Delayed Ack(TCP), Multicast flag
+ * @details 0 : Disable No Delayed ACK option\n
+ * 1 : Enable No Delayed ACK option\n
+ * This bit is applied only during TCP mode (P[3:0] = 001).\n
+ * When this bit is It sends the ACK packet without delay as soon as a Data packet is received from a peer.\n
+ * When this bit is It sends the ACK packet after waiting for the timeout time configured by \ref _RTR_.
+ */
+#define Sn_MR_ND 0x20 ///< No Delayed Ack(TCP) flag
+
+/**
+ * @brief Support UDP Multicasting
+ * @details 0 : using IGMP version 2\n
+ * 1 : using IGMP version 1\n
+ * This bit is applied only during UDP mode(P[3:0] = 010 and MULTI = '1')
+ * It configures the version for IGMP messages (Join/Leave/Report).
+ */
+#define Sn_MR_MC Sn_MR_ND ///< Select IGMP version 1(0) or 2(1)
+
+/**
+ * @brief MAC filter enable in @ref Sn_MR_MACRAW mode
+ * @details 0 : disable MAC Filtering\n
+ * 1 : enable MAC Filtering\n
+ * This bit is applied only during MACRAW mode(P[3:0] = 100.\n
+ * When set as W5100 can only receive broadcasting packet or packet sent to itself.
+ * When this bit is W5100 can receive all packets on Ethernet.
+ * If user wants to implement Hybrid TCP/IP stack,
+ * it is recommended that this bit is set as for reducing host overhead to process the all received packets.
+ */
+#define Sn_MR_MF 0x40 ///< Use MAC filter
+#define Sn_MR_MFEN Sn_MR_MF
+
+
+/* Sn_MR Default values */
+/**
+ * @brief Support UDP Multicasting
+ * @details 0 : disable Multicasting\n
+ * 1 : enable Multicasting\n
+ * This bit is applied only during UDP mode(P[3:0] = 010).\n
+ * To use multicasting, \ref Sn_DIPR & \ref Sn_DPORT should be respectively configured with the multicast group IP address & port number
+ * before Socket n is opened by OPEN command of \ref Sn_CR.
+ */
+#define Sn_MR_MULTI 0x80 ///< support multicating
+
+/* Sn_CR values */
+/**
+ * @brief Initialize or open socket
+ * @details Socket n is initialized and opened according to the protocol selected in Sn_MR(P3:P0).
+ * The table below shows the value of \ref Sn_SR corresponding to \ref Sn_MR.\n
+ *
+ *
\b Sn_MR (P[3:0])
\b Sn_SR
+ *
Sn_MR_CLOSE (000)
--
+ *
Sn_MR_TCP (001)
SOCK_INIT (0x13)
+ *
Sn_MR_UDP (010)
SOCK_UDP (0x22)
+ *
S0_MR_IPRAW (011)
SOCK_IPRAW (0x32)
+ *
S0_MR_MACRAW (100)
SOCK_MACRAW (0x42)
+ *
S0_MR_PPPoE (101)
SOCK_PPPoE (0x5F)
+ *
+ */
+#define Sn_CR_OPEN 0x01 ///< initialize or open socket
+
+/**
+ * @brief Wait connection request in TCP mode(Server mode)
+ * @details This is valid only in TCP mode (Sn_MR(P3:P0) = \ref Sn_MR_TCP).//
+ * In this mode, Socket n operates as a 'TCP server' and waits for connection-request (SYN packet) from any 'TCP client'.//
+ * The \ref Sn_SR changes the state from SOCK_INIT to SOCKET_LISTEN.//
+ * When a 'TCP client' connection request is successfully established,
+ * the \ref Sn_SR changes from SOCK_LISTEN to SOCK_ESTABLISHED and the Sn_IR(0) becomes
+ * But when a 'TCP client' connection request is failed, Sn_IR(3) becomes and the status of \ref Sn_SR changes to SOCK_CLOSED.
+ */
+#define Sn_CR_LISTEN 0x02 ///< wait connection request in tcp mode(Server mode)
+
+/**
+ * @brief Send connection request in TCP mode(Client mode)
+ * @details To connect, a connect-request (SYN packet) is sent to TCP serverconfigured by \ref Sn_DIPR & Sn_DPORT(destination address & port).
+ * If the connect-request is successful, the \ref Sn_SR is changed to \ref SOCK_ESTABLISHED and the Sn_IR(0) becomes \n\n
+ * The connect-request fails in the following three cases.\n
+ * 1. When a @b ARPTO occurs (\ref Sn_IR[3] = '1') because destination hardware address is not acquired through the ARP-process.\n
+ * 2. When a @b SYN/ACK packet is not received and @b TCPTO (Sn_IR(3) ='1')\n
+ * 3. When a @b RST packet is received instead of a @b SYN/ACK packet. In these cases, \ref Sn_SR is changed to \ref SOCK_CLOSED.
+ * @note This is valid only in TCP mode and operates when Socket n acts as TCP client
+ */
+#define Sn_CR_CONNECT 0x04 ///< send connection request in tcp mode(Client mode)
+
+/**
+ * @brief Send closing request in TCP mode
+ * @details Regardless of TCP serveror TCP client the DISCON command processes the disconnect-process (Active closeor Passive close.\n
+ * @par Active close
+ * it transmits disconnect-request(FIN packet) to the connected peer\n
+ * @par Passive close
+ * When FIN packet is received from peer, a FIN packet is replied back to the peer.\n
+ * @details When the disconnect-process is successful (that is, FIN/ACK packet is received successfully), \ref Sn_SR is changed to \ref SOCK_CLOSED.\n
+ * Otherwise, TCPTO occurs (Sn_IR(3)='1') and then \ref Sn_SR is changed to \ref SOCK_CLOSED.
+ * @note Valid only in TCP mode.
+ */
+#define Sn_CR_DISCON 0x08 ///< send closing reqeuset in tcp mode
+
+/**
+ * @brief Close socket
+ * @details Sn_SR is changed to \ref SOCK_CLOSED.
+ */
+#define Sn_CR_CLOSE 0x10
+
+/**
+ * @brief Update TX buffer pointer and send data
+ * @details SEND transmits all the data in the Socket n TX buffer.\n
+ * For more details, please refer to Socket n TX Free Size Register (\ref Sn_TX_FSR), Socket n,
+ * TX Write Pointer Register(\ref Sn_TX_WR), and Socket n TX Read Pointer Register(\ref Sn_TX_RD).
+ */
+#define Sn_CR_SEND 0x20
+
+/**
+ * @brief Send data with MAC address, so without ARP process
+ * @details The basic operation is same as SEND.\n
+ * Normally SEND transmits data after destination hardware address is acquired by the automatic ARP-process(Address Resolution Protocol).\n
+ * But SEND_MAC transmits data without the automatic ARP-process.\n
+ * In this case, the destination hardware address is acquired from \ref Sn_DHAR configured by host, instead of APR-process.
+ * @note Valid only in UDP mode.
+ */
+#define Sn_CR_SEND_MAC 0x21
+
+/**
+ * @brief Send keep alive message
+ * @details It checks the connection status by sending 1byte keep-alive packet.\n
+ * If the peer can not respond to the keep-alive packet during timeout time, the connection is terminated and the timeout interrupt will occur.
+ * @note Valid only in TCP mode.
+ */
+#define Sn_CR_SEND_KEEP 0x22
+
+/**
+ * @brief Update RX buffer pointer and receive data
+ * @details RECV completes the processing of the received data in Socket n RX Buffer by using a RX read pointer register (\ref Sn_RX_RD).\n
+ * For more details, refer to Socket n RX Received Size Register (\ref Sn_RX_RSR), Socket n RX Write Pointer Register (\ref Sn_RX_WR),
+ * and Socket n RX Read Pointer Register (\ref Sn_RX_RD).
+ */
+#define Sn_CR_RECV 0x40
+
+/**
+ * @brief PPPoE connection
+ * @details PPPoE connection begins by transmitting PPPoE discovery packet
+ */
+#define Sn_CR_PCON 0x23
+
+/**
+ * @brief Closes PPPoE connection
+ * @details Closes PPPoE connection
+ */
+#define Sn_CR_PDISCON 0x24
+
+/**
+ * @brief REQ message transmission
+ * @details In each phase, it transmits REQ message.
+ */
+#define Sn_CR_PCR 0x25
+
+/**
+ * @brief NAK massage transmission
+ * @details In each phase, it transmits NAK message.
+ */
+#define Sn_CR_PCN 0x26
+
+/**
+ * @brief REJECT message transmission
+ * @details In each phase, it transmits REJECT message.
+ */
+#define Sn_CR_PCJ 0x27
+
+/* Sn_IR values */
+/**
+ * @brief PPP Receive Interrupt
+ * @details PPP Receive Interrupts when the option which is not supported is received.
+ */
+#define Sn_IR_PRECV 0x80
+
+/**
+ * @brief PPP Fail Interrupt
+ * @details PPP Fail Interrupts when PAP Authentication is failed.
+ */
+#define Sn_IR_PFAIL 0x40
+
+/**
+ * @brief PPP Next Phase Interrupt
+ * @details PPP Next Phase Interrupts when the phase is changed during ADSL connection process.
+ */
+#define Sn_IR_PNEXT 0x20
+
+/**
+ * @brief SEND_OK Interrupt
+ * @details This is issued when SEND command is completed.
+ */
+#define Sn_IR_SENDOK 0x10 ///< complete sending
+
+/**
+ * @brief TIMEOUT Interrupt
+ * @details This is issued when ARPTO or TCPTO occurs.
+ */
+#define Sn_IR_TIMEOUT 0x08 ///< assert timeout
+
+/**
+ * @brief RECV Interrupt
+ * @details This is issued whenever data is received from a peer.
+ */
+#define Sn_IR_RECV 0x04
+
+/**
+ * @brief DISCON Interrupt
+ * @details This is issued when FIN or FIN/ACK packet is received from a peer.
+ */
+#define Sn_IR_DISCON 0x02
+
+/**
+ * @brief CON Interrupt
+ * @details This is issued one time when the connection with peer is successful and then \ref Sn_SR is changed to \ref SOCK_ESTABLISHED.
+ */
+#define Sn_IR_CON 0x01
+
+/* Sn_SR values */
+/**
+ * @brief Closed
+ * @details This indicates that Socket n is released.\n
+ * When DICON, CLOSE command is ordered, or when a timeout occurs, it is changed to \ref SOCK_CLOSED regardless of previous status.
+ */
+#define SOCK_CLOSED 0x00 ///< closed
+
+/**
+ * @brief Initiate state
+ * @details This indicates Socket n is opened with TCP mode.\n
+ * It is changed to \ref SOCK_INIT when Sn_MR(P[3:0]) = 001)and OPEN command is ordered.\n
+ * After \ref SOCK_INIT, user can use LISTEN /CONNECT command.
+ */
+#define SOCK_INIT 0x13 ///< init state
+
+/**
+ * @brief Listen state
+ * @details This indicates Socket n is operating as TCP servermode and waiting for connection-request (SYN packet) from a peer (TCP client).\n
+ * It will change to \ref SOCK_ESTABLISHED when the connection-request is successfully accepted.\n
+ * Otherwise it will change to \ref SOCK_CLOSED after TCPTO occurred (Sn_IR(TIMEOUT) = '1').
+ */
+#define SOCK_LISTEN 0x14
+
+/**
+ * @brief Connection state
+ * @details This indicates Socket n sent the connect-request packet (SYN packet) to a peer.\n
+ * It is temporarily shown when \ref Sn_SR is changed from \ref SOCK_INIT to \ref SOCK_ESTABLISHED by CONNECT command.\n
+ * If connect-accept(SYN/ACK packet) is received from the peer at SOCK_SYNSENT, it changes to \ref SOCK_ESTABLISHED.\n
+ * Otherwise, it changes to \ref SOCK_CLOSED after TCPTO (\ref Sn_IR[TIMEOUT] = '1') is occurred.
+ */
+#define SOCK_SYNSENT 0x15
+
+/**
+ * @brief Connection state
+ * @details It indicates Socket n successfully received the connect-request packet (SYN packet) from a peer.\n
+ * If socket n sends the response (SYN/ACK packet) to the peer successfully, it changes to \ref SOCK_ESTABLISHED. \n
+ * If not, it changes to \ref SOCK_CLOSED after timeout occurs (\ref Sn_IR[TIMEOUT] = '1').
+ */
+#define SOCK_SYNRECV 0x16
+
+/**
+ * @brief Success to connect
+ * @details This indicates the status of the connection of Socket n.\n
+ * It changes to \ref SOCK_ESTABLISHED when the TCP SERVERprocessed the SYN packet from the TCP CLIENTduring \ref SOCK_LISTEN, or
+ * when the CONNECT command is successful.\n
+ * During \ref SOCK_ESTABLISHED, DATA packet can be transferred using SEND or RECV command.
+ */
+#define SOCK_ESTABLISHED 0x17
+
+/**
+ * @brief Closing state
+ * @details These indicate Socket n is closing.\n
+ * These are shown in disconnect-process such as active-close and passive-close.\n
+ * When Disconnect-process is successfully completed, or when timeout occurs, these change to \ref SOCK_CLOSED.
+ */
+#define SOCK_FIN_WAIT 0x18
+
+/**
+ * @brief Closing state
+ * @details These indicate Socket n is closing.\n
+ * These are shown in disconnect-process such as active-close and passive-close.\n
+ * When Disconnect-process is successfully completed, or when timeout occurs, these change to \ref SOCK_CLOSED.
+ */
+#define SOCK_CLOSING 0x1A
+
+/**
+ * @brief Closing state
+ * @details These indicate Socket n is closing.\n
+ * These are shown in disconnect-process such as active-close and passive-close.\n
+ * When Disconnect-process is successfully completed, or when timeout occurs, these change to \ref SOCK_CLOSED.
+ */
+#define SOCK_TIME_WAIT 0x1B
+
+/**
+ * @brief Closing state
+ * @details This indicates Socket n received the disconnect-request (FIN packet) from the connected peer.\n
+ * This is half-closing status, and data can be transferred.\n
+ * For full-closing, DISCON command is used. But For just-closing, @ref Sn_CR_CLOSE command is used.
+ */
+#define SOCK_CLOSE_WAIT 0x1C
+
+/**
+ * @brief Closing state
+ * @details This indicates Socket n is waiting for the response (FIN/ACK packet) to the disconnect-request (FIN packet) by passive-close.\n
+ * It changes to \ref SOCK_CLOSED when Socket n received the response successfully, or when timeout occurs (\ref Sn_IR[TIMEOUT] = '1').
+ */
+#define SOCK_LAST_ACK 0x1D
+
+/**
+ * @brief UDP socket
+ * @details This indicates Socket n is opened in UDP mode(Sn_MR(P[3:0]) = 010).\n
+ * It changes to SOCK_UDP when Sn_MR(P[3:0]) = 010 and @ref Sn_CR_OPEN command is ordered.\n
+ * Unlike TCP mode, data can be transfered without the connection-process.
+ */
+#define SOCK_UDP 0x22 ///< udp socket
+
+/**
+ * @brief IP raw mode socket
+ * @details TThe socket is opened in IPRAW mode. The SOCKET status is change to SOCK_IPRAW when @ref Sn_MR (P3:P0) is
+ * Sn_MR_IPRAW and @ref Sn_CR_OPEN command is used.\n
+ * IP Packet can be transferred without a connection similar to the UDP mode.
+*/
+#define SOCK_IPRAW 0x32 ///< ip raw mode socket
+
+/**
+ * @brief MAC raw mode socket
+ * @details This indicates Socket 0 is opened in MACRAW mode (@ref Sn_MR(P[3:0]) = '100' and n=0) and is valid only in Socket 0.\n
+ * It changes to SOCK_MACRAW when @ref Sn_MR(P[3:0]) = '100' and @ref Sn_CR_OPEN command is ordered.\n
+ * Like UDP mode socket, MACRAW mode Socket 0 can transfer a MAC packet (Ethernet frame) without the connection-process.
+ */
+#define SOCK_MACRAW 0x42 ///< mac raw mode socket
+
+/**
+ * @brief PPPoE mode socket
+ * @details It is the status that SOCKET0 is open as PPPoE mode. It is changed to SOCK_PPPoE in case of S0_CR=OPEN and S0_MR
+ * (P3:P0)=S0_MR_PPPoE.\n
+ * It is temporarily used at the PPPoE
+connection.
+ */
+#define SOCK_PPPOE 0x5F ///< pppoe socket
+
+// IP PROTOCOL
+#define IPPROTO_IP 0 ///< Dummy for IP
+#define IPPROTO_ICMP 1 ///< Control message protocol
+#define IPPROTO_IGMP 2 ///< Internet group management protocol
+#define IPPROTO_GGP 3 ///< GW^2 (deprecated)
+#define IPPROTO_TCP 6 ///< TCP
+#define IPPROTO_PUP 12 ///< PUP
+#define IPPROTO_UDP 17 ///< UDP
+#define IPPROTO_IDP 22 ///< XNS idp
+#define IPPROTO_ND 77 ///< UNOFFICIAL net disk protocol
+#define IPPROTO_RAW 255 ///< Raw IP packet
+
+/**
+ * @brief Enter a critical section
+ *
+ * @details It is provided to protect your shared code which are executed without distribution. \n \n
+ *
+ * In non-OS environment, It can be just implemented by disabling whole interrupt.\n
+ * In OS environment, You can replace it to critical section api supported by OS.
+ *
+ * \sa WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF()
+ * \sa WIZCHIP_CRITICAL_EXIT()
+ */
+#define WIZCHIP_CRITICAL_ENTER() WIZCHIP.CRIS._enter()
+
+#ifdef _exit
+#undef _exit
+#endif
+
+/**
+ * @brief Exit a critical section
+ *
+ * @details It is provided to protect your shared code which are executed without distribution. \n\n
+ *
+ * In non-OS environment, It can be just implemented by disabling whole interrupt. \n
+ * In OS environment, You can replace it to critical section api supported by OS.
+ *
+ * @sa WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF()
+ * @sa WIZCHIP_CRITICAL_ENTER()
+ */
+#define WIZCHIP_CRITICAL_EXIT() WIZCHIP.CRIS._exit()
+
+
+
+////////////////////////
+// Basic I/O Function //
+////////////////////////
+//
+//M20150601 : uint16_t AddrSel --> uint32_t AddrSel
+//
+/**
+ * @ingroup Basic_IO_function_W5100
+ * @brief It reads 1 byte value from a register.
+ * @param AddrSel Register address
+ * @return The value of register
+ */
+uint8_t WIZCHIP_READ (uint32_t AddrSel);
+
+/**
+ * @ingroup Basic_IO_function_W5100
+ * @brief It writes 1 byte value to a register.
+ * @param AddrSel Register address
+ * @param wb Write data
+ * @return void
+ */
+void WIZCHIP_WRITE(uint32_t AddrSel, uint8_t wb );
+
+/**
+ * @ingroup Basic_IO_function_W5100
+ * @brief It reads sequence data from registers.
+ * @param AddrSel Register address
+ * @param pBuf Pointer buffer to read data
+ * @param len Data length
+ */
+void WIZCHIP_READ_BUF (uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
+
+/**
+ * @ingroup Basic_IO_function_W5100
+ * @brief It writes sequence data to registers.
+ * @param AddrSel Register address
+ * @param pBuf Pointer buffer to write data
+ * @param len Data length
+ */
+void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
+
+
+/////////////////////////////////
+// Common Register IO function //
+/////////////////////////////////
+
+/**
+ * @ingroup Common_register_access_function_W5100
+ * @brief Set Mode Register
+ * @param (uint8_t)mr The value to be set.
+ * @sa getMR()
+ */
+#if (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_)
+ #define setMR(mr) WIZCHIP_WRITE(MR,mr)
+#else
+ #define setMR(mr) (*((uint8_t*)MR) = mr)
+#endif
+
+/**
+ * @ingroup Common_register_access_function_W5100
+ * @brief Get @ref MR.
+ * @return uint8_t. The value of Mode register.
+ * @sa setMR()
+ */
+#if (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_)
+ #define getMR() WIZCHIP_READ(MR)
+#else
+ #define getMR() (*(uint8_t*)MR)
+#endif
+
+/**
+ * @ingroup Common_register_access_function_W5100
+ * @brief Set @ref GAR.
+ * @param (uint8_t*)gar Pointer variable to set gateway IP address. It should be allocated 4 bytes.
+ * @sa getGAR()
+ */
+#define setGAR(gar) \
+ WIZCHIP_WRITE_BUF(GAR,gar,4)
+
+/**
+ * @ingroup Common_register_access_function_W5100
+ * @brief Get @ref GAR.
+ * @param (uint8_t*)gar Pointer variable to get gateway IP address. It should be allocated 4 bytes.
+ * @sa setGAR()
+ */
+#define getGAR(gar) \
+ WIZCHIP_READ_BUF(GAR,gar,4)
+
+/**
+ * @ingroup Common_register_access_function_W5100
+ * @brief Set @ref SUBR.
+ * @param (uint8_t*)subr Pointer variable to set subnet mask address. It should be allocated 4 bytes.
+ * @note If subr is null pointer, set the backup subnet to SUBR. \n
+ * If subr is 0.0.0.0, back up SUBR and clear it. \n
+ * Otherwize, set subr to SUBR
+ * @sa getSUBR()
+ */
+#define setSUBR(subr) \
+ WIZCHIP_WRITE_BUF(SUBR,subr,4)
+
+/**
+ * @ingroup Common_register_access_function_W5100
+ * @brief Get @ref SUBR.
+ * @param (uint8_t*)subr Pointer variable to get subnet mask address. It should be allocated 4 bytes.
+ * @sa setSUBR()
+ */
+#define getSUBR(subr) \
+ WIZCHIP_READ_BUF(SUBR, subr, 4)
+
+/**
+ * @ingroup Common_register_access_function_W5100
+ * @brief Set @ref SHAR.
+ * @param (uint8_t*)shar Pointer variable to set local MAC address. It should be allocated 6 bytes.
+ * @sa getSHAR()
+ */
+#define setSHAR(shar) \
+ WIZCHIP_WRITE_BUF(SHAR, shar, 6)
+
+/**
+ * @ingroup Common_register_access_function_W5100
+ * @brief Get @ref SHAR.
+ * @param (uint8_t*)shar Pointer variable to get local MAC address. It should be allocated 6 bytes.
+ * @sa setSHAR()
+ */
+#define getSHAR(shar) \
+ WIZCHIP_READ_BUF(SHAR, shar, 6)
+
+/**
+ * @ingroup Common_register_access_function_W5100
+ * @brief Set @ref SIPR.
+ * @param (uint8_t*)sipr Pointer variable to set local IP address. It should be allocated 4 bytes.
+ * @sa getSIPR()
+*/
+#define setSIPR(sipr) \
+ WIZCHIP_WRITE_BUF(SIPR, sipr, 4)
+
+/**
+ * @ingroup Common_register_access_function_W5100
+ * @brief Get @ref SIPR.
+ * @param (uint8_t*)sipr Pointer variable to get local IP address. It should be allocated 4 bytes.
+ * @sa setSIPR()
+ */
+#define getSIPR(sipr) \
+ WIZCHIP_READ_BUF(SIPR, sipr, 4)
+
+/**
+ * @ingroup Common_register_access_function_W5100
+ * @brief Set \ref IR register
+ * @param (uint8_t)ir Value to set \ref IR register.
+ * @sa getIR()
+ */
+#define setIR(ir) \
+ WIZCHIP_WRITE(IR, (ir & 0xA0))
+/**
+ * @ingroup Common_register_access_function_W5100
+ * @brief Get \ref IR register
+ * @return uint8_t. Value of \ref IR register.
+ * @sa setIR()
+ */
+#define getIR() \
+ (WIZCHIP_READ(IR) & 0xA0)
+
+/**
+ * @ingroup Common_register_access_function_W5100
+ * @brief Set \ref _IMR_ register
+ * @param (uint8_t)imr Value to set @ref _IMR_ register.
+ * @sa getIMR()
+ */
+#define setIMR(imr) \
+ WIZCHIP_WRITE(_IMR_, imr)
+
+/**
+ * @ingroup Common_register_access_function_W5100
+ * @brief Get \ref _IMR_ register
+ * @return uint8_t. Value of @ref _IMR_ register.
+ * @sa setIMR()
+ */
+#define getIMR() \
+ WIZCHIP_READ(_IMR_)
+
+/**
+ * @ingroup Common_register_access_function_W5100
+ * @brief Set \ref _RTR_ register
+ * @param (uint16_t)rtr Value to set @ref _RTR_ register.
+ * @sa getRTR()
+ */
+#define setRTR(rtr) {\
+ WIZCHIP_WRITE(_RTR_, (uint8_t)(rtr >> 8)); \
+ WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(_RTR_,1), (uint8_t) rtr); \
+ }
+
+/**
+ * @ingroup Common_register_access_function_W5100
+ * @brief Get \ref _RTR_ register
+ * @return uint16_t. Value of @ref _RTR_ register.
+ * @sa setRTR()
+ */
+#define getRTR() \
+ (((uint16_t)WIZCHIP_READ(_RTR_) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(_RTR_,1)))
+
+/**
+ * @ingroup Common_register_access_function_W5100
+ * @brief Set \ref _RCR_ register
+ * @param (uint8_t)rcr Value to set @ref _RCR_ register.
+ * @sa getRCR()
+ */
+#define setRCR(rcr) \
+ WIZCHIP_WRITE(_RCR_, rcr)
+
+/**
+ * @ingroup Common_register_access_function_W5100
+ * @brief Get \ref _RCR_ register
+ * @return uint8_t. Value of @ref _RCR_ register.
+ * @sa setRCR()
+ */
+#define getRCR() \
+ WIZCHIP_READ(_RCR_)
+
+/**
+ * @ingroup Common_register_access_function_W5100
+ * @brief Get \ref RMSR register
+ * @sa getRMSR()
+ */
+#define setRMSR(rmsr) \
+ WIZCHIP_WRITE(RMSR) // Receicve Memory Size
+
+/**
+ * @ingroup Common_register_access_function_W5100
+ * @brief Get \ref RMSR register
+ * @return uint8_t. Value of @ref RMSR register.
+ * @sa setRMSR()
+ */
+ #define getRMSR() \
+ WIZCHIP_READ() // Receicve Memory Size
+
+/**
+ * @ingroup Common_register_access_function_W5100
+ * @brief Get \ref TMSR register
+ * @sa getTMSR()
+ */
+#define setTMSR(rmsr) \
+ WIZCHIP_WRITE(TMSR) // Receicve Memory Size
+
+/**
+ * @ingroup Common_register_access_function_W5100
+ * @brief Get \ref TMSR register
+ * @return uint8_t. Value of @ref TMSR register.
+ * @sa setTMSR()
+ */
+
+
+/**
+ * @ingroup Common_register_access_function_W5100
+ * @brief Get \ref PATR register
+ * @return uint16_t. Value to set \ref PATR register
+ */
+#define getPATR() \
+ (((uint16_t)WIZCHIP_READ(PATR) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(PATR,1)))
+
+/**
+ * @ingroup Common_register_access_function_W5100
+ * @brief Get \ref PPPALGO register
+ * @return uint8_t. Value to set \ref PPPALGO register
+ */
+#define getPPPALGO() \
+ WIZCHIP_READ(PPPALGO)
+
+
+/**
+ * @ingroup Common_register_access_function_W5100
+ * @brief Set \ref PTIMER register
+ * @param (uint8_t)ptimer Value to set \ref PTIMER register.
+ * @sa getPTIMER()
+ */
+#define setPTIMER(ptimer) \
+ WIZCHIP_WRITE(PTIMER, ptimer)
+
+/**
+ * @ingroup Common_register_access_function_W5100
+ * @brief Get \ref PTIMER register
+ * @return uint8_t. Value of @ref PTIMER register.
+ * @sa setPTIMER()
+ */
+#define getPTIMER() \
+ WIZCHIP_READ(PTIMER)
+
+/**
+ * @ingroup Common_register_access_function_W5100
+ * @brief Set \ref PMAGIC register
+ * @param (uint8_t)pmagic Value to set @ref PMAGIC register.
+ * @sa getPMAGIC()
+ */
+#define setPMAGIC(pmagic) \
+ WIZCHIP_WRITE(PMAGIC, pmagic)
+
+/**
+ * @ingroup Common_register_access_function_W5100
+ * @brief Get \ref PMAGIC register
+ * @return uint8_t. Value of @ref PMAGIC register.
+ * @sa setPMAGIC()
+ */
+#define getPMAGIC() \
+ WIZCHIP_READ(PMAGIC)
+
+///////////////////////////////////
+// Socket N register I/O function //
+///////////////////////////////////
+/**
+ * @ingroup Socket_register_access_function_W5100
+ * @brief Set @ref Sn_MR register
+ * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_ expect bit 4.
+ * @param mr Value to set @ref Sn_MR
+ * @sa getSn_MR()
+ */
+#define setSn_MR(sn, mr) \
+ WIZCHIP_WRITE(Sn_MR(sn),mr)
+
+/**
+ * @ingroup Socket_register_access_function_W5100
+ * @brief Get @ref Sn_MR register
+ * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_ expect bit 4.
+ * @return Value of @ref Sn_MR.
+ * @sa setSn_MR()
+ */
+#define getSn_MR(sn) \
+ WIZCHIP_READ(Sn_MR(sn))
+
+/**
+ * @ingroup Socket_register_access_function_W5100
+ * @brief Set @ref Sn_CR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param (uint8_t)cr Value to set @ref Sn_CR
+ * @sa getSn_CR()
+ */
+#define setSn_CR(sn, cr) \
+ WIZCHIP_WRITE(Sn_CR(sn), cr)
+
+/**
+ * @ingroup Socket_register_access_function_W5100
+ * @brief Get @ref Sn_CR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint8_t. Value of @ref Sn_CR.
+ * @sa setSn_CR()
+ */
+#define getSn_CR(sn) \
+ WIZCHIP_READ(Sn_CR(sn))
+
+/**
+ * @ingroup Socket_register_access_function_W5100
+ * @brief Set @ref Sn_IR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param (uint8_t)ir Value to set @ref Sn_IR
+ * @sa getSn_IR()
+ */
+#define setSn_IR(sn, ir) \
+ WIZCHIP_WRITE(Sn_IR(sn), ir)
+
+/**
+ * @ingroup Socket_register_access_function_W5100
+ * @brief Get @ref Sn_IR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint8_t. Value of @ref Sn_IR.
+ * @sa setSn_IR()
+ */
+#define getSn_IR(sn) \
+ WIZCHIP_READ(Sn_IR(sn))
+
+/**
+ * @ingroup Socket_register_access_function_W5100
+ * @brief Get @ref Sn_SR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint8_t. Value of @ref Sn_SR.
+ */
+#define getSn_SR(sn) \
+ WIZCHIP_READ(Sn_SR(sn))
+
+/**
+ * @ingroup Socket_register_access_function_W5100
+ * @brief Set @ref Sn_PORT register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param (uint16_t)port Value to set @ref Sn_PORT.
+ * @sa getSn_PORT()
+ */
+#define setSn_PORT(sn, port) { \
+ WIZCHIP_WRITE(Sn_PORT(sn), (uint8_t)(port >> 8)); \
+ WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_PORT(sn),1), (uint8_t) port); \
+ }
+
+/**
+ * @ingroup Socket_register_access_function_W5100
+ * @brief Get @ref Sn_PORT register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint16_t. Value of @ref Sn_PORT.
+ * @sa setSn_PORT()
+ */
+#define getSn_PORT(sn) \
+ (((uint16_t)WIZCHIP_READ(Sn_PORT(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_PORT(sn),1)))
+
+/**
+ * @ingroup Socket_register_access_function_W5100
+ * @brief Set @ref Sn_DHAR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param (uint8_t*)dhar Pointer variable to set socket n destination hardware address. It should be allocated 6 bytes.
+ * @sa getSn_DHAR()
+ */
+#define setSn_DHAR(sn, dhar) \
+ WIZCHIP_WRITE_BUF(Sn_DHAR(sn), dhar, 6)
+
+/**
+ * @ingroup Socket_register_access_function_W5100
+ * @brief Get @ref Sn_DHAR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param (uint8_t*)dhar Pointer variable to get socket n destination hardware address. It should be allocated 6 bytes.
+ * @sa setSn_DHAR()
+ */
+#define getSn_DHAR(sn, dhar) \
+ WIZCHIP_READ_BUF(Sn_DHAR(sn), dhar, 6)
+
+/**
+ * @ingroup Socket_register_access_function_W5100
+ * @brief Set @ref Sn_DIPR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param (uint8_t*)dipr Pointer variable to set socket n destination IP address. It should be allocated 4 bytes.
+ * @sa getSn_DIPR()
+ */
+#define setSn_DIPR(sn, dipr) \
+ WIZCHIP_WRITE_BUF(Sn_DIPR(sn), dipr, 4)
+
+/**
+ * @ingroup Socket_register_access_function_W5100
+ * @brief Get @ref Sn_DIPR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param (uint8_t*)dipr Pointer variable to get socket n destination IP address. It should be allocated 4 bytes.
+ * @sa SetSn_DIPR()
+ */
+#define getSn_DIPR(sn, dipr) \
+ WIZCHIP_READ_BUF(Sn_DIPR(sn), dipr, 4)
+
+/**
+ * @ingroup Socket_register_access_function_W5100
+ * @brief Set @ref Sn_DPORT register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param (uint16_t)dport Value to set @ref Sn_DPORT
+ * @sa getSn_DPORT()
+ */
+#define setSn_DPORT(sn, dport) { \
+ WIZCHIP_WRITE(Sn_DPORT(sn), (uint8_t) (dport>>8)); \
+ WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_DPORT(sn),1), (uint8_t) dport); \
+ }
+
+/**
+ * @ingroup Socket_register_access_function_W5100
+ * @brief Get @ref Sn_DPORT register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint16_t. Value of @ref Sn_DPORT.
+ * @sa setSn_DPORT()
+ */
+#define getSn_DPORT(sn) \
+ (((uint16_t)WIZCHIP_READ(Sn_DPORT(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_DPORT(sn),1)))
+
+/**
+ * @ingroup Socket_register_access_function_W5100
+ * @brief Set @ref Sn_MSSR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param (uint16_t)mss Value to set @ref Sn_MSSR
+ * @sa setSn_MSSR()
+ */
+#define setSn_MSSR(sn, mss) { \
+ WIZCHIP_WRITE(Sn_MSSR(sn), (uint8_t)(mss>>8)); \
+ WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_MSSR(sn),1), (uint8_t) mss); \
+ }
+
+/**
+ * @ingroup Socket_register_access_function_W5100
+ * @brief Get @ref Sn_MSSR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint16_t. Value of @ref Sn_MSSR.
+ * @sa setSn_MSSR()
+ */
+#define getSn_MSSR(sn) \
+ (((uint16_t)WIZCHIP_READ(Sn_MSSR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_MSSR(sn),1)))
+
+/**
+ * @ingroup Socket_register_access_function_W5100
+ * @brief Set @ref Sn_PROTO register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param (uint8_t)proto Value to set \ref Sn_PROTO
+ * @sa getSn_PROTO()
+ */
+#define setSn_PROTO(sn, proto) \
+ WIZCHIP_WRITE(Sn_TOS(sn), tos)
+
+/**
+ * @ingroup Socket_register_access_function_W5100
+ * @brief Get @ref Sn_PROTO register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint8_t. Value of @ref Sn_PROTO.
+ * @sa setSn_PROTO()
+ */
+#define getSn_PROTO(sn) \
+ WIZCHIP_READ(Sn_TOS(sn))
+
+/**
+ * @ingroup Socket_register_access_function_W5100
+ * @brief Set @ref Sn_TOS register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param (uint8_t)tos Value to set @ref Sn_TOS
+ * @sa getSn_TOS()
+ */
+#define setSn_TOS(sn, tos) \
+ WIZCHIP_WRITE(Sn_TOS(sn), tos)
+
+/**
+ * @ingroup Socket_register_access_function_W5100
+ * @brief Get @ref Sn_TOS register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_ .
+ * @return uint8_t. Value of Sn_TOS.
+ * @sa setSn_TOS()
+ */
+#define getSn_TOS(sn) \
+ WIZCHIP_READ(Sn_TOS(sn))
+
+/**
+ * @ingroup Socket_register_access_function_W5100
+ * @brief Set @ref Sn_TTL register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_ .
+ * @param (uint8_t)ttl Value to set @ref Sn_TTL
+ * @sa getSn_TTL()
+ */
+#define setSn_TTL(sn, ttl) \
+ WIZCHIP_WRITE(Sn_TTL(sn), ttl)
+
+/**
+ * @ingroup Socket_register_access_function_W5100
+ * @brief Get @ref Sn_TTL register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_ .
+ * @return uint8_t. Value of @ref Sn_TTL.
+ * @sa setSn_TTL()
+ */
+#define getSn_TTL(sn) \
+ WIZCHIP_READ(Sn_TTL(sn))
+
+/**
+ * @ingroup Socket_register_access_function_W5100
+ * @brief Set @ref Sn_RXMEM_SIZE register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_ .
+ * @param (uint8_t)rxmemsize Value to set \ref Sn_RXMEM_SIZE
+ * @sa getSn_RXMEM_SIZE()
+ */
+#define setSn_RXMEM_SIZE(sn, rxmemsize) \
+ WIZCHIP_WRITE(RMSR, (WIZCHIP_READ(RMSR) & ~(0x03 << (2*sn))) | (rxmemsize << (2*sn)))
+#define setSn_RXBUF_SIZE(sn,rxmemsize) setSn_RXMEM_SIZE(sn,rxmemsize)
+
+/**
+ * @ingroup Socket_register_access_function_W5100
+ * @brief Get @ref Sn_RXMEM_SIZE register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint8_t. Value of @ref Sn_RXMEM.
+ * @sa setSn_RXMEM_SIZE()
+ */
+#define getSn_RXMEM_SIZE(sn) \
+ ((WIZCHIP_READ(RMSR) & (0x03 << (2*sn))) >> (2*sn))
+#define getSn_RXBUF_SIZE(sn) getSn_RXMEM_SIZE(sn)
+
+/**
+ * @ingroup Socket_register_access_function_W5100
+ * @brief Set @ref Sn_TXMEM_SIZE register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param (uint8_t)txmemsize Value to set \ref Sn_TXMEM_SIZE
+ * @sa getSn_TXMEM_SIZE()
+ */
+#define setSn_TXMEM_SIZE(sn, txmemsize) \
+ WIZCHIP_WRITE(TMSR, (WIZCHIP_READ(TMSR) & ~(0x03 << (2*sn))) | (txmemsize << (2*sn)))
+#define setSn_TXBUF_SIZE(sn, txmemsize) setSn_TXMEM_SIZE(sn,txmemsize)
+
+/**
+ * @ingroup Socket_register_access_function_W5100
+ * @brief Get @ref Sn_TXMEM_SIZE register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint8_t. Value of @ref Sn_TXMEM_SIZE.
+ * @sa setSn_TXMEM_SIZE()
+ */
+#define getSn_TXMEM_SIZE(sn) \
+ ((WIZCHIP_READ(TMSR) & (0x03 << (2*sn))) >> (2*sn))
+#define getSn_TXBUF_SIZE(sn) getSn_TXMEM_SIZE(sn)
+
+/**
+ * @ingroup Socket_register_access_function_W5100
+ * @brief Get @ref Sn_TX_FSR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint16_t. Value of @ref Sn_TX_FSR.
+ */
+uint16_t getSn_TX_FSR(uint8_t sn);
+
+/**
+ * @ingroup Socket_register_access_function_W5100
+ * @brief Get @ref Sn_TX_RD register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint16_t. Value of @ref Sn_TX_RD.
+ */
+#define getSn_TX_RD(sn) \
+ (((uint16_t)WIZCHIP_READ(Sn_TX_RD(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_RD(sn),1)))
+
+/**
+ * @ingroup Socket_register_access_function_W5100
+ * @brief Set @ref Sn_TX_WR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param (uint16_t)txwr Value to set @ref Sn_TX_WR
+ * @sa GetSn_TX_WR()
+ */
+#define setSn_TX_WR(sn, txwr) { \
+ WIZCHIP_WRITE(Sn_TX_WR(sn), (uint8_t)(txwr>>8)); \
+ WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_TX_WR(sn),1), (uint8_t) txwr); \
+ }
+
+/**
+ * @ingroup Socket_register_access_function_W5100
+ * @brief Get @ref Sn_TX_WR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint16_t. Value of @ref Sn_TX_WR.
+ * @sa setSn_TX_WR()
+ */
+#define getSn_TX_WR(sn) \
+ (((uint16_t)WIZCHIP_READ(Sn_TX_WR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_WR(sn),1)))
+
+/**
+ * @ingroup Socket_register_access_function_W5100
+ * @brief Get @ref Sn_RX_RSR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint16_t. Value of @ref Sn_RX_RSR.
+ */
+uint16_t getSn_RX_RSR(uint8_t sn);
+
+/**
+ * @ingroup Socket_register_access_function_W5100
+ * @brief Set @ref Sn_RX_RD register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param (uint16_t)rxrd Value to set @ref Sn_RX_RD
+ * @sa getSn_RX_RD()
+ */
+#define setSn_RX_RD(sn, rxrd) { \
+ WIZCHIP_WRITE(Sn_RX_RD(sn), (uint8_t)(rxrd>>8)); \
+ WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_RX_RD(sn),1), (uint8_t) rxrd); \
+ }
+
+/**
+ * @ingroup Socket_register_access_function_W5100
+ * @brief Get @ref Sn_RX_RD register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @regurn uint16_t. Value of @ref Sn_RX_RD.
+ * @sa setSn_RX_RD()
+ */
+#define getSn_RX_RD(sn) \
+ (((uint16_t)WIZCHIP_READ(Sn_RX_RD(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RD(sn),1)))
+
+/**
+ * @ingroup Socket_register_access_function_W5100
+ * @brief Set @ref Sn_RX_WR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param (uint16_t)rxwr Value to set \ref Sn_RX_WR
+ * @sa getSn_RX_WR()
+ */
+#define setSn_RX_WR(sn, rxwr) { \
+ WIZCHIP_WRITE(Sn_RX_WR(sn), (uint8_t)(rxwr>>8)); \
+ WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_RX_WR(sn),1), (uint8_t) rxwr); \
+ }
+
+
+/**
+ * @ingroup Socket_register_access_function_W5100
+ * @brief Get @ref Sn_RX_WR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint16_t. Value of @ref Sn_RX_WR.
+ */
+#define getSn_RX_WR(sn) \
+ (((uint16_t)WIZCHIP_READ(Sn_RX_WR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_WR(sn),1)))
+
+/**
+ * @ingroup Socket_register_access_function_W5100
+ * @brief Set @ref Sn_FRAG register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param (uint16_t)frag Value to set \ref Sn_FRAG
+ * @sa getSn_FRAG()
+ */
+#define setSn_FRAG(sn, frag) { \
+ WIZCHIP_WRITE(Sn_FRAG(sn), (uint8_t)(frag >>8)); \
+ WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_FRAG(sn),1), (uint8_t) frag); \
+ }
+
+/**
+ * @ingroup Socket_register_access_function_W5100
+ * @brief Get @ref Sn_FRAG register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint16_t. Value of @ref Sn_FRAG.
+ * @sa setSn_FRAG()
+ */
+#define getSn_FRAG(sn) \
+ (((uint16_t)WIZCHIP_READ(Sn_FRAG(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_FRAG(sn),1)))
+
+/**
+ * @ingroup Socket_register_access_function_W5100
+ * @brief Get the max RX buffer size of socket sn
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint16_t. Max buffer size
+ */
+#define getSn_RxMAX(sn) \
+ ((uint16_t)(1 << getSn_RXMEM_SIZE(sn)) << 10)
+
+
+/**
+ * @ingroup Socket_register_access_function_W5100
+ * @brief Get the max TX buffer size of socket sn
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint16_t. Max buffer size
+ */
+#define getSn_TxMAX(sn) \
+ ((uint16_t)(1 << getSn_TXMEM_SIZE(sn)) << 10)
+
+/**
+ * @ingroup Socket_register_access_function_W5100
+ * @brief Get the mask of socket sn RX buffer.
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint16_t. Mask value
+ */
+#define getSn_RxMASK(sn) \
+ (getSn_RxMAX(sn) - 1)
+
+/**
+ * @ingroup Socket_register_access_function_W5100
+ * @brief Get the mask of socket sn TX buffer
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint16_t. Mask value
+ */
+#define getSn_TxMASK(sn) \
+ (getSn_TxMAX(sn) - 1)
+
+/**
+ * @ingroup Socket_register_access_function_W5100
+ * @brief Get the base address of socket sn RX buffer.
+ * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint16_t. Value of Socket n RX buffer base address.
+ */
+uint32_t getSn_RxBASE(uint8_t sn);
+
+/**
+ * @ingroup Socket_register_access_function_W5100
+ * @brief Get the base address of socket sn TX buffer.
+ * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint16_t. Value of Socket n TX buffer base address.
+ */
+uint32_t getSn_TxBASE(uint8_t sn);
+
+/////////////////////////////////////
+// Sn_TXBUF & Sn_RXBUF IO function //
+/////////////////////////////////////
+/**
+ * @ingroup Basic_IO_function_W5100
+ * @brief It copies data to internal TX memory
+ *
+ * @details This function reads the Tx write pointer register and after that,
+ * it copies the wizdata(pointer buffer) of the length of len(variable) bytes to internal TX memory
+ * and updates the Tx write pointer register.
+ * This function is being called by send() and sendto() function also.
+ *
+ * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param wizdata Pointer buffer to write data
+ * @param len Data length
+ * @sa wiz_recv_data()
+ */
+void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint16_t len);
+
+/**
+ * @ingroup Basic_IO_function_W5100
+ * @brief It copies data to your buffer from internal RX memory
+ *
+ * @details This function read the Rx read pointer register and after that,
+ * it copies the received data from internal RX memory
+ * to wizdata(pointer variable) of the length of len(variable) bytes.
+ * This function is being called by recv() also.
+ *
+ * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param wizdata Pointer buffer to read data
+ * @param len Data length
+ * @sa wiz_send_data()
+ */
+void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len);
+
+/**
+ * @ingroup Basic_IO_function_W5100
+ * @brief It discard the received data in RX memory.
+ * @details It discards the data of the length of len(variable) bytes in internal RX memory.
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param len Data length
+ */
+void wiz_recv_ignore(uint8_t sn, uint16_t len);
+
+/// @cond DOXY_APPLY_CODE
+#endif
+/// @endcond
+
+#endif //_W5100_H_
+
+
+
diff --git a/Libraries/ioLibrary_Driver/Ethernet/W5100S/w5100s.c b/Libraries/ioLibrary_Driver/Ethernet/W5100S/w5100s.c
new file mode 100644
index 0000000..b0640d2
--- /dev/null
+++ b/Libraries/ioLibrary_Driver/Ethernet/W5100S/w5100s.c
@@ -0,0 +1,523 @@
+//*****************************************************************************
+//
+//! \file w5100S.c
+//! \brief W5100S HAL Interface.
+//! \version 1.0.0
+//! \date 2018/03/29
+//! \par Revision history
+//! <2018/03/29> 1st Release
+//! \author Peter
+//!
+//! Copyright (c) 2013, WIZnet Co., LTD.
+//! All rights reserved.
+//!
+//! Redistribution and use in source and binary forms, with or without
+//! modification, are permitted provided that the following conditions
+//! are met:
+//!
+//! * Redistributions of source code must retain the above copyright
+//! notice, this list of conditions and the following disclaimer.
+//! * Redistributions in binary form must reproduce the above copyright
+//! notice, this list of conditions and the following disclaimer in the
+//! documentation and/or other materials provided with the distribution.
+//! * Neither the name of the nor the names of its
+//! contributors may be used to endorse or promote products derived
+//! from this software without specific prior written permission.
+//!
+//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+//! THE POSSIBILITY OF SUCH DAMAGE.
+//
+//*****************************************************************************
+
+#include "w5100s.h"
+#include
+
+
+#if (_WIZCHIP_ == W5100S)
+/**
+@brief This function writes the data into W5100S registers.
+*/
+void WIZCHIP_WRITE(uint32_t AddrSel, uint8_t wb )
+{
+ uint8_t pTmpBuf[4];
+ int i;
+ WIZCHIP_CRITICAL_ENTER();
+ WIZCHIP.CS._select();
+
+#if( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_))
+ #if !defined (SPI_DMA)
+
+ WIZCHIP.IF.SPI._write_byte(0xF0);
+ WIZCHIP.IF.SPI._write_byte((AddrSel & 0xFF00) >> 8);
+ WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF) >> 0);
+ WIZCHIP.IF.SPI._write_byte(wb); // Data write (write 1byte data)
+ #else
+
+ pTmpBuf[0] = (0x00F00000 & 0x00FF0000) >> 16;
+ pTmpBuf[1] = (AddrSel & 0x0000FF00) >> 8;
+ pTmpBuf[2] = (AddrSel & 0x000000FF) >> 0;
+ pTmpBuf[3] = wb;
+
+ WIZCHIP.IF.SPI._write_burst(pTmpBuf, 4);
+ #endif
+#elif ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_5500_) )
+ #if !defined (SPI_DMA)
+ WIZCHIP.IF.SPI._write_byte((AddrSel & 0xFF00) >> 8);
+ WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF) >> 0);
+ WIZCHIP.IF.SPI._write_byte(0xF0);
+ WIZCHIP.IF.SPI._write_byte(wb); // Data write (write 1byte data)
+ #else
+
+ pTmpBuf[0] = (AddrSel & 0x0000FF00) >> 8;
+ pTmpBuf[1] = (AddrSel & 0x000000FF) >> 0;
+ pTmpBuf[2] = (0x00F00000 & 0x00FF0000) >> 16;
+ pTmpBuf[3] = wb;
+
+ WIZCHIP.IF.SPI._write_burst(pTmpBuf, 4);
+ #endif
+
+#elif ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_) )
+
+ //add indirect bus
+ //M20150601 : Rename the function for integrating with ioLibrary
+ //WIZCHIP.IF.BUS._write_byte(IDM_AR0,(AddrSel & 0xFF00) >> 8);
+ //WIZCHIP.IF.BUS._write_byte(IDM_AR1,(AddrSel & 0x00FF));
+ //WIZCHIP.IF.BUS._write_byte(IDM_DR,wb);
+ WIZCHIP.IF.BUS._write_data(IDM_AR0,(AddrSel & 0xFF00) >> 8);
+ WIZCHIP.IF.BUS._write_data(IDM_AR1,(AddrSel & 0x00FF));
+ WIZCHIP.IF.BUS._write_data(IDM_DR,wb);
+
+#else
+ #error "Unknown _WIZCHIP_IO_MODE_ in W5100. !!!"
+#endif
+
+ WIZCHIP.CS._deselect();
+ WIZCHIP_CRITICAL_EXIT();
+}
+/**
+@brief This function reads the value from W5100S registers.
+*/
+uint8_t WIZCHIP_READ(uint32_t AddrSel)
+{
+ uint8_t pTmpBuf[4];
+ uint8_t ret;
+ int i;
+ WIZCHIP_CRITICAL_ENTER();
+ WIZCHIP.CS._select();
+
+#if( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_))
+ #if !defined (SPI_DMA)
+ WIZCHIP.IF.SPI._write_byte(0x0F);
+ WIZCHIP.IF.SPI._write_byte((AddrSel & 0xFF00) >> 8);
+ WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF) >> 0);
+ ret = WIZCHIP.IF.SPI._read_byte();
+ #else
+
+ pTmpBuf[0] = (0x000F0000 & 0x00FF0000) >> 16;
+ pTmpBuf[1] = (AddrSel & 0x0000FF00) >> 8;
+ pTmpBuf[2] = (AddrSel & 0x000000FF) >> 0;
+
+ //WIZCHIP.IF.SPI._write_burst(pTmpBuf, 3);
+ WIZCHIP.IF.SPI._read_burst(pTmpBuf, 4);
+
+ ret = pTmpBuf[3];
+
+ #endif
+#elif ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_5500_) )
+ #if !defined (SPI_DMA)
+ WIZCHIP.IF.SPI._write_byte((AddrSel & 0xFF00) >> 8);
+ WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF) >> 0);
+ WIZCHIP.IF.SPI._write_byte(0x0F);
+ ret = WIZCHIP.IF.SPI._read_byte();
+ #else
+
+ pTmpBuf[0] = (AddrSel & 0x0000FF00) >> 8;
+ pTmpBuf[1] = (AddrSel & 0x000000FF) >> 0;
+ pTmpBuf[2] = (0x000F0000 & 0x00FF0000) >> 16;
+
+ WIZCHIP.IF.SPI._read_burst(pTmpBuf, 4);
+
+ ret = pTmpBuf[3];
+
+ #endif
+#elif ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_) )
+
+ //add indirect bus
+ //M20150601 : Rename the function for integrating with ioLibrary
+ //WIZCHIP.IF.BUS._write_byte(IDM_AR0,(AddrSel & 0xFF00) >> 8);
+ //WIZCHIP.IF.BUS._write_byte(IDM_AR1,(AddrSel & 0x00FF));
+ //ret = WIZCHIP.IF.BUS._read_byte(IDM_DR);
+ WIZCHIP.IF.BUS._write_data(IDM_AR0,(AddrSel & 0xFF00) >> 8);
+ WIZCHIP.IF.BUS._write_data(IDM_AR1,(AddrSel & 0x00FF));
+ ret = WIZCHIP.IF.BUS._read_data(IDM_DR);
+
+#else
+ #error "Unknown _WIZCHIP_IO_MODE_ in W5100S. !!!"
+#endif
+
+ WIZCHIP.CS._deselect();
+ WIZCHIP_CRITICAL_EXIT();
+ return ret;
+}
+
+
+/**
+@brief This function writes into W5100S memory(Buffer)
+*/
+void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len)
+{
+ uint8_t pTmpBuf[3];
+
+ uint16_t i = 0;
+ int j,k,l;
+ WIZCHIP_CRITICAL_ENTER();
+ WIZCHIP.CS._select(); //M20150601 : Moved here.
+
+#if((_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_))
+
+ #if !defined (SPI_DMA)
+ WIZCHIP.IF.SPI._write_byte(0xF0);
+ WIZCHIP.IF.SPI._write_byte((((uint16_t)(AddrSel+i)) & 0xFF00) >> 8);
+ WIZCHIP.IF.SPI._write_byte((((uint16_t)(AddrSel+i)) & 0x00FF) >> 0);
+
+ for(i = 0; i < len; i++)
+ {
+ WIZCHIP.IF.SPI._write_byte(pBuf[i]); // Data write (write 1byte data)
+ }
+ #else
+
+ pTmpBuf[0] = (0x00F00000 & 0x00FF0000) >> 16;
+ pTmpBuf[1] = (AddrSel & 0x0000FF00) >> 8;
+ pTmpBuf[2] = (AddrSel & 0x000000FF) >> 0;
+
+
+ WIZCHIP.IF.SPI._write_burst(pTmpBuf, 3);
+ WIZCHIP.IF.SPI._write_burst(pBuf, len);
+ #endif
+
+
+#elif ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_5500_) )
+ #if !defined (SPI_DMA)
+
+ WIZCHIP.IF.SPI._write_byte((((uint16_t)(AddrSel+i)) & 0xFF00) >> 8);
+ WIZCHIP.IF.SPI._write_byte((((uint16_t)(AddrSel+i)) & 0x00FF) >> 0);
+ WIZCHIP.IF.SPI._write_byte(0xF0);
+
+ for(i = 0; i < len; i++)
+ {
+ WIZCHIP.IF.SPI._write_byte(pBuf[i]); // Data write (write 1byte data)
+ }
+ #else
+
+ pTmpBuf[0] = (AddrSel & 0x0000FF00) >> 8;
+ pTmpBuf[1] = (AddrSel & 0x000000FF) >> 0;
+ pTmpBuf[2] = (0x00F00000 & 0x00FF0000) >> 16;
+
+
+ WIZCHIP.IF.SPI._write_burst(pTmpBuf, 3);
+ WIZCHIP.IF.SPI._write_burst(pBuf, len);
+ #endif
+
+#elif ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_) )
+ //M20150601 : Rename the function for integrating with ioLibrary
+
+#if !defined(BUS_DMA)
+ WIZCHIP.IF.BUS._write_data(IDM_AR0,(AddrSel & 0xFF00) >> 8);
+ WIZCHIP.IF.BUS._write_data(IDM_AR1,(AddrSel & 0x00FF));
+ for(i = 0 ; i < len; i++)
+ WIZCHIP.IF.BUS._write_data(IDM_DR,pBuf[i]);
+#else
+ WIZCHIP.IF.BUS._write_data(IDM_AR0,(AddrSel & 0xFF00) >> 8);
+ WIZCHIP.IF.BUS._write_data(IDM_AR1,(AddrSel & 0x00FF));
+ WIZCHIP.IF.BUS._write_burst(IDM_DR,pBuf,len);
+// setMR(getMR() & ~MR_AI);
+#endif
+
+#else
+ #error "Unknown _WIZCHIP_IO_MODE_ in W5100S. !!!!"
+#endif
+
+ WIZCHIP.CS._deselect(); //M20150601 : Moved here.
+ WIZCHIP_CRITICAL_EXIT();
+
+}
+
+/**
+@brief This function reads into W5100S memory(Buffer)
+*/
+
+void WIZCHIP_READ_BUF (uint32_t AddrSel, uint8_t* pBuf, uint16_t len)
+{
+ uint8_t pTmpBuf[3];
+ uint16_t i = 0;
+ WIZCHIP_CRITICAL_ENTER();
+ WIZCHIP.CS._select(); //M20150601 : Moved here.
+
+#if( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_) )
+
+ #if !defined (SPI_DMA)
+ WIZCHIP.IF.SPI._write_byte(0x0F);
+ WIZCHIP.IF.SPI._write_byte((uint16_t)((AddrSel+i) & 0xFF00) >> 8);
+ WIZCHIP.IF.SPI._write_byte((uint16_t)((AddrSel+i) & 0x00FF) >> 0);
+
+ for(i = 0; i < len; i++)
+ {
+ pBuf[i] = WIZCHIP.IF.SPI._read_byte();
+ }
+ #else
+
+ pTmpBuf[0] = (0x000F0000 & 0x00FF0000) >> 16;
+ pTmpBuf[1] = (AddrSel & 0x0000FF00) >> 8;
+ pTmpBuf[2] = (AddrSel & 0x000000FF) >> 0;
+
+ WIZCHIP.IF.SPI._write_burst(pTmpBuf, 3);
+ WIZCHIP.IF.SPI._read_burst(pBuf, len);
+ #endif
+
+#elif ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_5500_) )
+ #if !defined (SPI_DMA)
+
+ WIZCHIP.IF.SPI._write_byte((uint16_t)((AddrSel+i) & 0xFF00) >> 8);
+ WIZCHIP.IF.SPI._write_byte((uint16_t)((AddrSel+i) & 0x00FF) >> 0);
+ WIZCHIP.IF.SPI._write_byte(0x0F);
+
+ for(i = 0; i < len; i++)
+ {
+ pBuf[i] = WIZCHIP.IF.SPI._read_byte();
+ }
+ #else
+
+ pTmpBuf[0] = (AddrSel & 0x0000FF00) >> 8;
+ pTmpBuf[1] = (AddrSel & 0x000000FF) >> 0;
+ pTmpBuf[2] = (0x000F0000 & 0x00FF0000) >> 16;
+
+ WIZCHIP.IF.SPI._write_burst(pTmpBuf, 3);
+ WIZCHIP.IF.SPI._read_burst(pBuf, len);
+ #endif
+
+#elif ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_) )
+ //M20150601 : Rename the function for integrating with ioLibrary
+
+#if !defined(BUS_DMA)
+ WIZCHIP.IF.BUS._write_data(IDM_AR0,(AddrSel & 0xFF00) >> 8);
+ WIZCHIP.IF.BUS._write_data(IDM_AR1,(AddrSel & 0x00FF));
+ for(i = 0 ; i < len; i++)
+ pBuf[i] = WIZCHIP.IF.BUS._read_data(IDM_DR);
+#else
+ WIZCHIP.IF.BUS._write_data(IDM_AR0,(AddrSel & 0xFF00) >> 8);
+ WIZCHIP.IF.BUS._write_data(IDM_AR1,(AddrSel & 0x00FF));
+ WIZCHIP.IF.BUS._read_burst(IDM_DR,pBuf,len);
+
+#endif
+
+#else
+ #error "Unknown _WIZCHIP_IO_MODE_ in W5100S. !!!!"
+#endif
+
+ WIZCHIP.CS._deselect(); //M20150601 : Moved Here.
+ WIZCHIP_CRITICAL_EXIT();
+
+}
+
+///////////////////////////////////
+// Socket N regsiter IO function //
+///////////////////////////////////
+
+uint16_t getSn_TX_FSR(uint8_t sn)
+{
+ uint16_t val=0,val1=0;
+ do
+ {
+ val1 = WIZCHIP_READ(Sn_TX_FSR(sn));
+ val1 = (val1 << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn),1));
+ if (val1 != 0)
+ {
+ val = WIZCHIP_READ(Sn_TX_FSR(sn));
+ val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn),1));
+ }
+ }while (val != val1);
+ return val;
+}
+
+
+uint16_t getSn_RX_RSR(uint8_t sn)
+{
+ uint16_t val=0,val1=0;
+ do
+ {
+ val1 = WIZCHIP_READ(Sn_RX_RSR(sn));
+ val1 = (val1 << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn),1));
+ if (val1 != 0)
+ {
+ val = WIZCHIP_READ(Sn_RX_RSR(sn));
+ val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn),1));
+ }
+ }while (val != val1);
+ return val;
+}
+
+/////////////////////////////////////
+// Sn_TXBUF & Sn_RXBUF IO function //
+/////////////////////////////////////
+uint32_t getSn_RxBASE(uint8_t sn)
+{
+ int8_t i;
+#if ( _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_DIR_)
+ uint32_t rxbase = _W5100S_IO_BASE_ + _WIZCHIP_IO_RXBUF_;
+#else
+ uint32_t rxbase = _WIZCHIP_IO_RXBUF_;
+#endif
+ for(i = 0; i < sn; i++)
+ rxbase += getSn_RxMAX(i);
+
+ return rxbase;
+}
+
+uint32_t getSn_TxBASE(uint8_t sn)
+{
+ int8_t i;
+#if ( _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_DIR_)
+ uint32_t txbase = _W5100S_IO_BASE_ + _WIZCHIP_IO_TXBUF_;
+#else
+ uint32_t txbase = _WIZCHIP_IO_TXBUF_;
+#endif
+ for(i = 0; i < sn; i++)
+ txbase += getSn_TxMAX(i);
+ return txbase;
+}
+
+/**
+@brief This function is being called by send() and sendto() function also. for copy the data form application buffer to Transmite buffer of the chip.
+
+This function read the Tx write pointer register and after copy the data in buffer update the Tx write pointer
+register. User should read upper byte first and lower byte later to get proper value.
+And this function is being used for copy the data form application buffer to Transmite
+buffer of the chip. It calculate the actual physical address where one has to write
+the data in transmite buffer. Here also take care of the condition while it exceed
+the Tx memory uper-bound of socket.
+
+*/
+void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint16_t len)
+{
+ uint16_t ptr;
+ uint16_t size;
+ uint16_t dst_mask;
+ uint16_t dst_ptr;
+
+ ptr = getSn_TX_WR(sn);
+
+ dst_mask = ptr & getSn_TxMASK(sn);
+ dst_ptr = getSn_TxBASE(sn) + dst_mask;
+
+ if (dst_mask + len > getSn_TxMAX(sn))
+ {
+ size = getSn_TxMAX(sn) - dst_mask;
+ WIZCHIP_WRITE_BUF(dst_ptr, wizdata, size);
+ wizdata += size;
+ size = len - size;
+ dst_ptr = getSn_TxBASE(sn);
+ WIZCHIP_WRITE_BUF(dst_ptr, wizdata, size);
+ }
+ else
+ {
+ WIZCHIP_WRITE_BUF(dst_ptr, wizdata, len);
+ }
+
+ ptr += len;
+
+ setSn_TX_WR(sn, ptr);
+}
+
+
+/**
+@brief This function is being called by recv() also. This function is being used for copy the data form Receive buffer of the chip to application buffer.
+
+This function read the Rx read pointer register
+and after copy the data from receive buffer update the Rx write pointer register.
+User should read upper byte first and lower byte later to get proper value.
+It calculate the actual physical address where one has to read
+the data from Receive buffer. Here also take care of the condition while it exceed
+the Rx memory uper-bound of socket.
+*/
+void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len)
+{
+ uint16_t ptr;
+ uint16_t size;
+ uint16_t src_mask;
+ uint16_t src_ptr;
+
+ ptr = getSn_RX_RD(sn);
+
+ src_mask = (uint32_t)ptr & getSn_RxMASK(sn);
+ src_ptr = (getSn_RxBASE(sn) + src_mask);
+
+
+ if( (src_mask + len) > getSn_RxMAX(sn) )
+ {
+ size = getSn_RxMAX(sn) - src_mask;
+ WIZCHIP_READ_BUF((uint32_t)src_ptr, (uint8_t*)wizdata, size);
+ wizdata += size;
+ size = len - size;
+ src_ptr = getSn_RxBASE(sn);
+ WIZCHIP_READ_BUF(src_ptr, (uint8_t*)wizdata, size);
+ }
+ else
+ {
+ WIZCHIP_READ_BUF(src_ptr, (uint8_t*)wizdata, len);
+ }
+
+ ptr += len;
+
+ setSn_RX_RD(sn, ptr);
+}
+
+void wiz_recv_ignore(uint8_t sn, uint16_t len)
+{
+ uint16_t ptr;
+
+ ptr = getSn_RX_RD(sn);
+
+ ptr += len;
+ setSn_RX_RD(sn,ptr);
+}
+
+void wiz_mdio_write(uint8_t PHYMDIO_regadr, uint16_t var)
+{
+ WIZCHIP_WRITE(PHYRAR,PHYMDIO_regadr);
+ WIZCHIP_WRITE(PHYDIR, (uint8_t)(var >> 8));
+ WIZCHIP_WRITE(PHYDIR+1, (uint8_t)(var));
+ WIZCHIP_WRITE(PHYACR, PHYACR_WRITE);
+ while(WIZCHIP_READ(PHYACR)); //wait for command complete
+}
+
+uint16_t wiz_mdio_read(uint8_t PHYMDIO_regadr)
+{
+ WIZCHIP_WRITE(PHYRAR,PHYMDIO_regadr);
+ WIZCHIP_WRITE(PHYACR, PHYACR_READ);
+ while(WIZCHIP_READ(PHYACR)); //wait for command complete
+ return ((uint16_t)WIZCHIP_READ(PHYDOR) << 8) | WIZCHIP_READ(PHYDOR+1);
+}
+
+void wiz_delay_ms(uint32_t milliseconds)
+{
+ uint32_t i;
+ for(i = 0 ; i < milliseconds ; i++)
+ {
+ //Write any values to clear the TCNTCLKR register
+ setTCNTCLKR(0xff);
+
+ // Wait until counter register value reaches 10.(10 = 1ms : TCNTR is 100us tick counter register)
+ while(getTCNTR() < 0x0a){}
+ }
+}
+
+#endif
diff --git a/Libraries/ioLibrary_Driver/Ethernet/W5100S/w5100s.h b/Libraries/ioLibrary_Driver/Ethernet/W5100S/w5100s.h
new file mode 100644
index 0000000..b8809af
--- /dev/null
+++ b/Libraries/ioLibrary_Driver/Ethernet/W5100S/w5100s.h
@@ -0,0 +1,3316 @@
+//* ****************************************************************************
+//! \file w5100S.h
+//! \brief W5100S HAL Header File.
+//! \version 1.0.0
+//! \date 2018/03/29
+//! \par Revision history
+//! <2018/03/29> 1st Release
+//! \author Peter
+//! \copyright
+//!
+//! Copyright (c) 2013, WIZnet Co., LTD.
+//! All rights reserved.
+//!
+//! Redistribution and use in source and binary forms, with or without
+//! modification, are permitted provided that the following conditions
+//! are met:
+//!
+//! * Redistributions of source code must retain the above copyright
+//! notice, this list of conditions and the following disclaimer.
+//! * Redistributions in binary form must reproduce the above copyright
+//! notice, this list of conditions and the following disclaimer in the
+//! documentation and/or other materials provided with the distribution.
+//! * Neither the name of the nor the names of its
+//! contributors may be used to endorse or promote products derived
+//! from this software without specific prior written permission.
+//!
+//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+//! THE POSSIBILITY OF SUCH DAMAGE.
+//
+//*****************************************************************************
+
+
+#ifndef _W5100S_H_
+#define _W5100S_H_
+
+#include
+#include "wizchip_conf.h"
+
+/// \cond DOXY_APPLY_CODE
+#if (_WIZCHIP_ == W5100S)
+/// \endcond
+
+#define _WIZCHIP_SN_BASE_ (0x0400)
+#define _WIZCHIP_SN_SIZE_ (0x0100)
+#define _WIZCHIP_IO_TXBUF_ (0x4000) /* Internal Tx buffer address of the iinchip */
+#define _WIZCHIP_IO_RXBUF_ (0x6000) /* Internal Rx buffer address of the iinchip */
+
+
+#define WIZCHIP_CREG_BLOCK 0x00 ///< Common register block
+#define WIZCHIP_SREG_BLOCK(N) (_WIZCHIP_SN_BASE_+ _WIZCHIP_SN_SIZE_*N) ///< Socket N register block
+
+#define WIZCHIP_OFFSET_INC(ADDR, N) (ADDR + N) ///< Increase offset address
+
+#if (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_DIR_)
+ #define _W5100S_IO_BASE_ _WIZCHIP_IO_BASE_
+#elif (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_)
+ #define IDM_OR ((_WIZCHIP_IO_BASE + 0x0000))
+ #define IDM_AR0 ((_WIZCHIP_IO_BASE_ + 0x0001))
+ #define IDM_AR1 ((_WIZCHIP_IO_BASE_ + 0x0002))
+ #define IDM_DR ((_WIZCHIP_IO_BASE_ + 0x0003))
+ #define _W5100S_IO_BASE_ 0x0000
+#elif (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_)
+ #define _W5100S_IO_BASE_ 0x0000
+#endif
+
+///////////////////////////////////////
+// Definition For Legacy Chip Driver //
+///////////////////////////////////////
+#define IINCHIP_READ(ADDR) WIZCHIP_READ(ADDR) ///< The defined for legacy chip driver
+#define IINCHIP_WRITE(ADDR,VAL) WIZCHIP_WRITE(ADDR,VAL) ///< The defined for legacy chip driver
+#define IINCHIP_READ_BUF(ADDR,BUF,LEN) WIZCHIP_READ_BUF(ADDR,BUF,LEN) ///< The defined for legacy chip driver
+#define IINCHIP_WRITE_BUF(ADDR,BUF,LEN) WIZCHIP_WRITE(ADDR,BUF,LEN) ///< The defined for legacy chip driver
+
+
+//----------- defgroup --------------------------------
+
+/**
+ * @defgroup W5100S W5100S
+ * @brief WHIZCHIP register defines and I/O functions of @b W5100S.
+ *
+ * - @ref WIZCHIP_register_W5100S: @ref Common_register_group_W5100S and @ref Socket_register_group_W5100S
+ * - @ref WIZCHIP_IO_Functions_W5100S: @ref Basic_IO_function_W5100S, @ref Common_register_access_function_W5100S and @ref Special_function_W5100S
+ */
+
+ /**
+ * @defgroup WIZCHIP_register_W5100S WIZCHIP register
+ * @ingroup W5100S
+ * @brief WIZCHIP register defines register group of W5100S .
+ *
+ * - \ref Common_register_group_W5100S : Common register group W5100S
+ * - \ref Socket_register_group_W5100S : \c SOCKET n register group W5100S
+ */
+
+
+/**
+ * @defgroup WIZCHIP_IO_Functions_W5100S WIZCHIP I/O functions
+ * @ingroup W5100S
+ * @brief This supports the basic I/O functions for \ref WIZCHIP_register_W5100S.
+ *
+ * - Basic I/O function \n
+ * WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF(), wiz_recv_data(), wiz_recv_ignore(), wiz_send_data() \n\n
+ *
+ * - \ref Common_register_group_W5100S access functions \n
+ * -# @b Mode \n
+ * getMR(), setMR()
+ * -# @b Interrupt \n
+ * getIR(), setIR(), getIMR(), setIMR(),
+ * -# Network Information \n
+ * getSHAR(), setSHAR(), getGAR(), setGAR(), getSUBR(), setSUBR(), getSIPR(), setSIPR()
+ * -# @b Retransmission \n
+ * getRCR(), setRCR(), getRTR(), setRTR()
+ * -# @b PPPoE \n
+ * getPTIMER(), setPTIMER(), getPMAGIC(), getPMAGIC()
+ *
+ * - \ref Socket_register_group_W5100S access functions \n
+ * -# SOCKET control \n
+ * getSn_MR(), setSn_MR(), getSn_CR(), setSn_CR(), getSn_IR(), setSn_IR()
+ * -# SOCKET information \n
+ * getSn_SR(), getSn_DHAR(), setSn_DHAR(), getSn_PORT(), setSn_PORT(), getSn_DIPR(), setSn_DIPR(), getSn_DPORT(), setSn_DPORT()
+ * getSn_MSSR(), setSn_MSSR()
+ * -# SOCKET communication \n
+ * getSn_RXMEM_SIZE(), setSn_RXMEM_SIZE(), getSn_TXMEM_SIZE(), setSn_TXMEM_SIZE() \n
+ * getSn_TX_RD(), getSn_TX_WR(), setSn_TX_WR() \n
+ * getSn_RX_RD(), setSn_RX_RD(), getSn_RX_WR() \n
+ * getSn_TX_FSR(), getSn_RX_RSR()
+ * -# IP header field \n
+ * getSn_FRAG(), setSn_FRAG(), getSn_TOS(), setSn_TOS() \n
+ * getSn_TTL(), setSn_TTL()
+ */
+
+/**
+ * @defgroup Common_register_group_W5100S Common register
+ * @ingroup WIZCHIP_register_W5100S
+ * @brief Common register group\n
+ * It set the basic for the networking\n
+ * It set the configuration such as interrupt, network information, ICMP, etc.
+ * @details
+ * @sa MR : Mode register.
+ * @sa GAR, SUBR, SHAR, SIPR
+ * @sa IR, Sn_IR, _IMR_ : Interrupt.
+ * @sa _RTR_, _RCR_ : Data retransmission.
+ * @sa PTIMER, PMAGIC : PPPoE.
+ */
+
+
+ /**
+ * @defgroup Socket_register_group_W5100S Socket register
+ * @ingroup WIZCHIP_register_W5100S
+ * @brief Socket register group\n
+ * Socket register configures and control SOCKETn which is necessary to data communication.
+ * @details
+ * @sa Sn_MR, Sn_CR, Sn_IR : SOCKETn Control
+ * @sa Sn_SR, Sn_PORT, Sn_DHAR, Sn_DIPR, Sn_DPORT : SOCKETn Information
+ * @sa Sn_MSSR, Sn_TOS, Sn_TTL, Sn_FRAGR : Internet protocol.
+ * @sa Sn_RXMEM_SIZE, Sn_TXMEM_SIZE, Sn_TX_FSR, Sn_TX_RD, Sn_TX_WR, Sn_RX_RSR, Sn_RX_RD, Sn_RX_WR : Data communication
+ */
+
+ /**
+ * @defgroup Basic_IO_function_W5100S Basic I/O function
+ * @ingroup WIZCHIP_IO_Functions_W5100S
+ * @brief These are basic input/output functions to read values from register or write values to register.
+ */
+
+/**
+ * @defgroup Common_register_access_function_W5100S Common register access functions
+ * @ingroup WIZCHIP_IO_Functions_W5100S
+ * @brief These are functions to access common registers.
+ */
+
+/**
+ * @defgroup Socket_register_access_function_W5100S Socket register access functions
+ * @ingroup WIZCHIP_IO_Functions_W5100S
+ * @brief These are functions to access socket registers.
+ */
+
+ /**
+ * @defgroup Special_function_W5100S Special functions
+ * @ingroup WIZCHIP_IO_Functions_W5100S
+ * @brief These are special functions to access to the PHY
+ */
+
+ //-----------------------------------------------------------------------------------
+
+//----------------------------- W5100S Common Registers IOMAP -----------------------------
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief Mode Register address(R/W)\n
+ * \ref MR is used for S/W reset, ping block mode, PPPoE mode and etc.
+ * @details Each bit of \ref MR defined as follows.
+ *
+ *
7
6
5
4
3
2
1
0
+ *
RST
Reserved
WOL
PB
PPPoE
Reserved
AI
IND
+ *
+ * - \ref MR_RST : Reset
+ * - \ref MR_PB : Ping block
+ * - \ref MR_PPPOE : PPPoE mode
+ * - \ref MR_AI : Address Auto-Increment in Indirect Bus Interface
+ * - \ref MR_IND : Indirect Bus Interface mode
+ */
+#if _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_
+ #define MR (_WIZCHIP_IO_BASE_ + (0x0000)) // Mode
+#else
+ #define MR (_W5100S_IO_BASE_ + (0x0000)) // Mode
+#endif
+
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief Gateway IP Register address(R/W)
+ * @details \ref GAR configures the default gateway address.
+ */
+#define GAR (_W5100S_IO_BASE_ + (0x0001)) // GW Address
+
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief Subnet mask Register address(R/W)
+ * @details \ref SUBR configures the subnet mask address.
+ */
+#define SUBR (_W5100S_IO_BASE_ + (0x0005)) // SN Mask Address
+
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief Source MAC Register address(R/W)
+ * @details \ref SHAR configures the source hardware address.
+ */
+#define SHAR (_W5100S_IO_BASE_ + (0x0009)) // Source Hardware Address
+
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief Source IP Register address(R/W)
+ * @details \ref SIPR configures the source IP address.
+ */
+#define SIPR (_W5100S_IO_BASE_ + (0x000F)) // Source IP Address
+
+// Reserved (_W5100S_IO_BASE_ + (0x0013))
+// Reserved (_W5100S_IO_BASE_ + (0x0014))
+
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief Interrupt Register(R/W)
+ * @details \ref IR indicates the interrupt status. Each bit of \ref IR will be still until the bit will be written to by the host.
+ * If \ref IR is not equal to x00 INTn PIN is asserted to low until it is x00\n\n
+ * Each bit of \ref IR defined as follows.
+ *
+ *
7
6
5
4
3
2
1
0
+ *
CONFLICT
UNREACH
PPPoE
Reserved
S3_INT
S2_INT
S1_INT
S0_INT
+ *
+ * - \ref IR_CONFLICT : IP conflict
+ * - \ref IR_UNREACH : Destination unreachable
+ * - \ref IR_PPPoE : PPPoE connection close
+ * - \ref IR_SOCK(3) : SOCKET 3 Interrupt
+ * - \ref IR_SOCK(2) : SOCKET 2 Interrupt
+ * - \ref IR_SOCK(1) : SOCKET 1 Interrupt
+ * - \ref IR_SOCK(0) : SOCKET 0 Interrupt
+ */
+#define IR (_W5100S_IO_BASE_ + (0x0015)) // Interrupt
+
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief Socket Interrupt Mask Register(R/W)
+ * @details Each bit of \ref _IMR_ corresponds to each bit of \ref IR.
+ * When a bit of \ref _IMR_ is and the corresponding bit of \ref IR is set, Interrupt will be issued.
+ */
+#define _IMR_ (_W5100S_IO_BASE_ + (0x0016)) // Socket Interrupt Mask
+
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief Timeout register address( 1 is 100us )(R/W)
+ * @details \ref _RTR_ configures the retransmission timeout period. The unit of timeout period is 100us and the default of \ref _RTR_ is x07D0or 000
+ * And so the default timeout period is 200ms(100us X 2000). During the time configured by \ref _RTR_, W5100S waits for the peer response
+ * to the packet that is transmitted by \ref Sn_CR (CONNECT, DISCON, CLOSE, SEND, SEND_MAC, SEND_KEEP command).
+ * If the peer does not respond within the \ref _RTR_ time, W5100S retransmits the packet or issues timeout.
+ */
+#define _RTR_ (_W5100S_IO_BASE_ + (0x0017)) // Retry Time
+
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief Retry count register(R/W)
+ * @details \ref _RCR_ configures the number of time of retransmission.
+ * When retransmission occurs as many as ref _RCR_+1 Timeout interrupt is issued (\ref Sn_IR_TIMEOUT = '1').
+ */
+#define _RCR_ (_W5100S_IO_BASE_ + (0x0019)) // Retry Count
+
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief Receive Memory Size Register
+ * @details \ref RMSR register configures RX bufffer Size of the SOCKET
+ * The sum of the RX buffers can not exceed 8kB.
+ *
+ *
7
6
5
4
3
2
1
0
+ *
S3-1
S3-0
S2-1
S2-0
S1-1
S1-0
S0-1
S0-0
+ *
+ *
+ *
Memory Size
Sn-1
Sn-0
+ *
1KB
0
0
+ *
2KB
0
1
+ *
4KB
1
0
+ *
8KB
1
1
+ *
+ */
+#define RMSR (_W5100S_IO_BASE_ + (0x001A)) // Receive Memory Size
+
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief Transmit Memory Size Register
+ * @details \ref TMSR register configures TX bufffer Size of the SOCKET
+ * The sum of the TX buffers can not exceed 8kB.
+ *
+ *
7
6
5
4
3
2
1
0
+ *
S3-1
S3-0
S2-1
S2-0
S1-1
S1-0
S0-1
S0-0
+ *
+ *
+ *
Memory Size
Sn-1
Sn-0
+ *
1KB
0
0
+ *
2KB
0
1
+ *
4KB
1
0
+ *
8KB
1
1
+ *
+ */
+#define TMSR (_W5100S_IO_BASE_ + (0x001B)) // Transmit Memory Size
+
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief Interrupt register 2
+ * @details \ref IR2 indicates the interrupt status.
+ * Each bit of IR2 will be still until the bit will be written to by the host.
+ *
+ * - \ref Sn_MR_MULTI : Support UDP Multicasting
+ * - \ref Sn_MR_MF : Support MACRAW
+ * - \ref Sn_MR_ND : No Delayed Ack(TCP) flag
+ * - \ref Sn_MR_MC : IGMP version used in UDP mulitcasting
+ * - Protocol
+ *
+ *
Protocol[3]
Protocol[2]
Protocol[1]
Protocol[0]
@b Meaning
+ *
0
0
0
0
Closed
+ *
0
0
0
1
TCP
+ *
0
0
1
0
UDP
+ *
0
1
0
0
MACRAW
+ *
+ * - In case of Socket 0
+ *
+ *
Protocol[3]
Protocol[2]
Protocol[1]
Protocol[0]
@b Meaning
+ *
0
1
0
0
MACRAW
+ *
0
1
0
1
PPPoE
+ *
+ * - \ref Sn_MR_MACRAW : MAC LAYER RAW SOCK \n
+ * - \ref Sn_MR_UDP : UDP
+ * - \ref Sn_MR_TCP : TCP
+ * - \ref Sn_MR_CLOSE : Unused socket
+ * @note MACRAW mode should be only used in Socket 0.
+ */
+#define Sn_MR(sn) (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0000)) // socket Mode register
+
+/**
+ * @ingroup Socket_register_group_W5100S
+ * @brief Socket command register(R/W)
+ * @details This is used to set the command for Socket n such as OPEN, CLOSE, CONNECT, LISTEN, SEND, and RECEIVE.\n
+ * After W5100S accepts the command, the \ref Sn_CR register is automatically cleared to 0x00.
+ * Even though \ref Sn_CR is cleared to 0x00, the command is still being processed.\n
+ * To check whether the command is completed or not, please check the \ref Sn_IR or \ref Sn_SR.
+ * - \ref Sn_CR_OPEN : Initialize or open socket.
+ * - \ref Sn_CR_LISTEN : Wait connection request in TCP mode(Server mode)
+ * - \ref Sn_CR_CONNECT : Send connection request in TCP mode(Client mode)
+ * - \ref Sn_CR_DISCON : Send closing request in TCP mode.
+ * - \ref Sn_CR_CLOSE : Close socket.
+ * - \ref Sn_CR_SEND : Update TX buffer pointer and send data.
+ * - \ref Sn_CR_SEND_MAC : Send data with MAC address, so without ARP process.
+ * - \ref Sn_CR_SEND_KEEP : Send keep alive message.
+ * - \ref Sn_CR_RECV : Update RX buffer pointer and receive data.
+ * - In case of S0_MR(P3:P0) = S0_MR_PPPoE
+ *
+ *
Value
Symbol
Description
+ *
0x23
PCON
PPPoE connection begins by transmitting PPPoE discovery packet
+ *
0x24
PDISCON
Closes PPPoE connection
+ *
0x25
PCR
In each phase, it transmits REQ message.
+ *
0x26
PCN
In each phase, it transmits NAK message.
+ *
0x27
PCJ
In each phase, it transmits REJECT message.
+ *
+ */
+#define Sn_CR(sn) (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0001)) // channel Sn_CR register
+
+/**
+ * @ingroup Socket_register_group_W5100S
+ * @brief Socket interrupt register(R)
+ * @details \ref Sn_IR indicates the status of Socket Interrupt such as establishment, termination, receiving data, timeout).\n
+ * When an interrupt occurs and the corresponding bit \ref IR_SOCK(N) in \ref _IMR_ are set, \ref IR_SOCK(N) in \ref IR becomes '1'.\n
+ * In order to clear the \ref Sn_IR bit, the host should write the bit to \n
+ *
+ *
7
6
5
4
3
2
1
0
+ *
PRECV
PFAIL
PNEXT
SEND_OK
TIMEOUT
RECV
DISCON
CON
+ *
+ * - \ref Sn_IR_PRECV : PPP Receive Interrupt
+ * - \ref Sn_IR_PFAIL : PPP Fail Interrupt
+ * - \ref Sn_IR_PNEXT : PPP Next Phase Interrupt
+ * - \ref Sn_IR_SENDOK : SEND_OK Interrupt
+ * - \ref Sn_IR_TIMEOUT : TIMEOUT Interrupt
+ * - \ref Sn_IR_RECV : RECV Interrupt
+ * - \ref Sn_IR_DISCON : DISCON Interrupt
+ * - \ref Sn_IR_CON : CON Interrupt
+ */
+#define Sn_IR(sn) (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0002)) // channel interrupt register
+
+/**
+ * @ingroup Socket_register_group_W5100S
+ * @brief Socket status register(R)
+ * @details \ref Sn_SR indicates the status of Socket n.\n
+ * The status of Socket n is changed by \ref Sn_CR or some special control packet as SYN, FIN packet in TCP.
+ * @par Normal status
+ * - \ref SOCK_CLOSED : Closed
+ * - \ref SOCK_INIT : Initiate state
+ * - \ref SOCK_LISTEN : Listen state
+ * - \ref SOCK_ESTABLISHED : Success to connect
+ * - \ref SOCK_CLOSE_WAIT : Closing state
+ * - \ref SOCK_UDP : UDP socket
+ * - \ref SOCK_MACRAW : MAC raw mode socket
+ *@par Temporary status during changing the status of Socket n.
+ * - \ref SOCK_SYNSENT : This indicates Socket n sent the connect-request packet (SYN packet) to a peer.
+ * - \ref SOCK_SYNRECV : It indicates Socket n successfully received the connect-request packet (SYN packet) from a peer.
+ * - \ref SOCK_FIN_WAIT : Connection state
+ * - \ref SOCK_CLOSING : Closing state
+ * - \ref SOCK_TIME_WAIT : Closing state
+ * - \ref SOCK_LAST_ACK : Closing state
+ */
+#define Sn_SR(sn) (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0003)) // channel status register
+
+/**
+ * @ingroup Socket_register_group_W5100S
+ * @brief source port register(R/W)
+ * @details \ref Sn_PORT configures the source port number of Socket n.
+ * It is valid when Socket n is used in TCP/UDP mode. It should be set before OPEN command is ordered.
+*/
+#define Sn_PORT(sn) (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0004)) // source port register
+
+/**
+ * @ingroup Socket_register_group_W5100S
+ * @brief Peer MAC register address(R/W)
+ * @details \ref Sn_DHAR configures the destination hardware address of Socket n when using SEND_MAC command in UDP mode or
+ * it indicates that it is acquired in ARP-process by CONNECT/SEND command.
+ */
+#define Sn_DHAR(sn) (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0006)) // Peer MAC register address
+
+/**
+ * @ingroup Socket_register_group_W5100S
+ * @brief Peer IP register address(R/W)
+ * @details \ref Sn_DIPR configures or indicates the destination IP address of Socket n. It is valid when Socket n is used in TCP/UDP mode.
+ * In TCP client mode, it configures an IP address of TCP server before CONNECT command.
+ * In TCP server mode, it indicates an IP address of TCP client after successfully establishing connection.
+ * In UDP mode, it configures an IP address of peer to be received the UDP packet by SEND or SEND_MAC command.
+ */
+#define Sn_DIPR(sn) (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x000C)) // Peer IP register address
+
+/**
+ * @ingroup Socket_register_group_W5100S
+ * @brief Peer port register address(R/W)
+ * @details \ref Sn_DPORT configures or indicates the destination port number of Socket n. It is valid when Socket n is used in TCP/UDP mode.
+ * In TCP clientmode, it configures the listen port number of TCP server before CONNECT command.
+ * In TCP Servermode, it indicates the port number of TCP client after successfully establishing connection.
+ * In UDP mode, it configures the port number of peer to be transmitted the UDP packet by SEND/SEND_MAC command.
+ */
+#define Sn_DPORT(sn) (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0010)) // Peer port register address
+
+/**
+ * @ingroup Socket_register_group_W5100S
+ * @brief Maximum Segment Size(Sn_MSSR0) register address(R/W)
+ * @details \ref Sn_MSSR configures or indicates the MTU(Maximum Transfer Unit) of Socket n.
+ */
+#define Sn_MSSR(sn) (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0012)) // Maximum Segment Size(Sn_MSSR0) register address
+
+/**
+ * @ingroup Socket_register_group_W5100S
+ * @brief IP Protocol(PROTO) Register(R/W)
+ * @details \ref Sn_PROTO that sets the protocol number field of the IP header at the IP layer. It is
+ * valid only in IPRAW mode, and ignored in other modes.
+ */
+#define Sn_PROTO(sn) (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0014)) // Protocol of IP Header field register in IP raw mode
+
+/**
+ * @ingroup Socket_register_group_W5100S
+ * @brief IP Type of Service(TOS) Register(R/W)
+ * @details \ref Sn_TOS configures the TOS(Type Of Service field in IP Header) of Socket n.
+ * It is set before OPEN command.
+ */
+#define Sn_TOS(sn) (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + 0x0015) // IP Type of Service(TOS) Register
+
+/**
+ * @ingroup Socket_register_group_W5100S
+ * @brief IP Time to live(TTL) Register(R/W)
+ * @details \ref Sn_TTL configures the TTL(Time To Live field in IP header) of Socket n.
+ * It is set before OPEN command.
+ */
+#define Sn_TTL(sn) (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0016)) // IP Time to live(TTL) Register
+
+// Reserved (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0017))
+// Reserved (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0018))
+// Reserved (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0019))
+// Reserved (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x001A))
+// Reserved (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x001B))
+// Reserved (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x001C))
+// Reserved (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x001D))
+
+
+
+/**
+ * @ingroup Socket_register_group_W5100S
+ * @brief Receive memory size register(R/W)
+ * @details @ref Sn_RXBUF_SIZE configures the RX buffer block size of Socket n.
+ * Socket n RX Buffer Block size can be configured with 1,2,4 and 8Kbytes.
+ * If a different size is configured, the data cannot be normally received from a peer.
+ * Although Socket n RX Buffer Block size is initially configured to 2Kbytes,
+ * user can re-configure its size using @ref Sn_RXBUF_SIZE. The total sum of @ref Sn_RXBUF_SIZE can not be exceed 8Kbytes.
+ * When exceeded, the data reception error is occurred.
+ */
+#define Sn_RXBUF_SIZE(sn) (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x001E))
+
+/**
+ * @ingroup Socket_register_group_W5100S
+ * @brief Transmit memory size register(R/W)
+ * @details @ref Sn_TXBUF_SIZE configures the TX buffer block size of Socket n. Socket n TX Buffer Block size can be configured with 1,2,4 and 8Kbytes.
+ * If a different size is configured, the data cannot be normally transmitted to a peer.
+ * Although Socket n TX Buffer Block size is initially configured to 2Kbytes,
+ * user can be re-configure its size using @ref Sn_TXBUF_SIZE. The total sum of @ref Sn_TXBUF_SIZE can not be exceed 8Kbytes.
+ * When exceeded, the data transmission error is occurred.
+ */
+#define Sn_TXBUF_SIZE(sn) (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x001F))
+
+
+/**
+ * @ingroup Socket_register_group_W5100S
+ * @brief Transmit free memory size register(R)
+ * @details \ref Sn_TX_FSR indicates the free size of Socket n TX Buffer Block. It is initialized to the configured size by \ref Sn_TXMEM_SIZE.
+ * Data bigger than \ref Sn_TX_FSR should not be saved in the Socket n TX Buffer because the bigger data overwrites the previous saved data not yet sent.
+ * Therefore, check before saving the data to the Socket n TX Buffer, and if data is equal or smaller than its checked size,
+ * transmit the data with SEND/SEND_MAC command after saving the data in Socket n TX buffer. But, if data is bigger than its checked size,
+ * transmit the data after dividing into the checked size and saving in the Socket n TX buffer.
+ */
+#define Sn_TX_FSR(sn) (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0020)) // Transmit free memory size register
+
+/**
+ * @ingroup Socket_register_group_W5100S
+ * @brief Transmit memory read pointer register address(R)
+ * @details \ref Sn_TX_RD is initialized by OPEN command. However, if Sn_MR(P[3:0]) is TCP mode(001), it is re-initialized while connecting with TCP.
+ * After its initialization, it is auto-increased by SEND command.
+ * SEND command transmits the saved data from the current \ref Sn_TX_RD to the \ref Sn_TX_WR in the Socket n TX Buffer.
+ * After transmitting the saved data, the SEND command increases the \ref Sn_TX_RD as same as the \ref Sn_TX_WR.
+ * If its increment value exceeds the maximum value 0xFFFF, (greater than 0x10000 and the carry bit occurs),
+ * then the carry bit is ignored and will automatically update with the lower 16bits value.
+ */
+#define Sn_TX_RD(sn) (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0022)) // Transmit memory read pointer register address
+
+/**
+ * @ingroup Socket_register_group_W5100S
+ * @brief Transmit memory write pointer register address(R/W)
+ * @details \ref Sn_TX_WR is initialized by OPEN command. However, if Sn_MR(P[3:0]) is TCP mode(001), it is re-initialized while connecting with TCP.\n
+ * It should be read or be updated like as follows.\n
+ * 1. Read the starting address for saving the transmitting data.\n
+ * 2. Save the transmitting data from the starting address of Socket n TX buffer.\n
+ * 3. After saving the transmitting data, update \ref Sn_TX_WR to the increased value as many as transmitting data size.
+ * If the increment value exceeds the maximum value 0xFFFF(greater than 0x10000 and the carry bit occurs),
+ * then the carry bit is ignored and will automatically update with the lower 16bits value.\n
+ * 4. Transmit the saved data in Socket n TX Buffer by using SEND/SEND command
+ */
+#define Sn_TX_WR(sn) (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0024)) // Transmit memory write pointer register address
+
+/**
+ * @ingroup Socket_register_group_W5100S
+ * @brief Received data size register(R)
+ * @details \ref Sn_RX_RSR indicates the data size received and saved in Socket n RX Buffer.
+ * \ref Sn_RX_RSR does not exceed the \ref Sn_RXMEM_SIZE and is calculated as the difference between
+ * Socket n RX Write Pointer (\ref Sn_RX_WR)and Socket n RX Read Pointer (\ref Sn_RX_RD)
+ */
+#define Sn_RX_RSR(sn) (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0026)) // Received data size register
+
+/**
+ * @ingroup Socket_register_group_W5100S
+ * @brief Read point of Receive memory(R/W)
+ * @details \ref Sn_RX_RD is initialized by OPEN command. Make sure to be read or updated as follows.\n
+ * 1. Read the starting save address of the received data.\n
+ * 2. Read data from the starting address of Socket n RX Buffer.\n
+ * 3. After reading the received data, Update \ref Sn_RX_RD to the increased value as many as the reading size.
+ * If the increment value exceeds the maximum value 0xFFFF, that is, is greater than 0x10000 and the carry bit occurs,
+ * update with the lower 16bits value ignored the carry bit.\n
+ * 4. Order RECV command is for notifying the updated \ref Sn_RX_RD to W5100S.
+ */
+#define Sn_RX_RD(sn) (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0028)) // Read point of Receive memory
+
+/**
+ * @ingroup Socket_register_group_W5100S
+ * @brief Write point of Receive memory(R)
+ * @details \ref Sn_RX_WR is initialized by OPEN command and it is auto-increased by the data reception.
+ * If the increased value exceeds the maximum value 0xFFFF, (greater than 0x10000 and the carry bit occurs),
+ * then the carry bit is ignored and will automatically update with the lower 16bits value.
+ */
+#define Sn_RX_WR(sn) (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x002A)) // Write point of Receive memory
+
+
+//todo
+/**
+ * @ingroup Socket_register_group_W5100S
+ * @brief Socket interrupt mask register
+ * @details Register address to configure the interrupt mask of the socket
+ * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_ expect bit 4.
+ *
+ */
+#define Sn_IMR(sn) (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x002C))
+
+/**
+ * @ingroup Socket_register_group_W5100S
+ * @brief Socket fragment field register
+ * @details Register to configure the Fragment field of IP Header
+ * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_ expect bit 4.
+ */
+#define Sn_FRAGR(sn) (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x002D)) // and +1
+
+/**
+ * @ingroup Socket_register_group_W5100S
+ * @brief Socket Mode register 2
+ * @details Register to set mode 2
+ * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_ expect bit 4.
+ */
+#define Sn_MR2(sn) (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x002F))
+
+/**
+ * @ingroup Socket_register_group_W5100S
+ * @brief Socket n Keep Alive Timer Register
+ * @details Register to set the transmission period of keep alive packet.
+ * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_ expect bit 4.
+ */
+#define Sn_KPALVTR(sn) (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0030))
+
+/** todo delete
+ * @ingroup Socket_register_group_W5100S
+ * @brief Socket n Timer Status Register
+ * @details
+ * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_ expect bit 4.
+ */
+//#define Sn_TSR(sn) (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0031))
+
+/**
+ * @ingroup Socket_register_group_W5100S
+ * @brief Socket n Retry Time-value Register
+ * @details Register to set the retry time value
+ * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_ expect bit 4.
+ */
+#define Sn_RTR(sn) (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0032))
+
+/**
+ * @ingroup Socket_register_group_W5100S
+ * @brief Socket n Retry Count-value Register
+ * @details Register to set the retry count value
+ * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_ expect bit 4.
+ */
+#define Sn_RCR(sn) (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0034))
+
+
+/*----------------------------- W5100S Register values -----------------------------*/
+
+/* MODE register values */
+/**
+ * @brief Reset
+ * @details If this bit is All internal registers will be initialized. It will be automatically cleared as after S/W reset.
+ */
+#define MR_RST 0x80 ///< reset
+
+
+/**
+ * @brief Ping block
+ * @details 0 : Disable Ping block\n
+ * 1 : Enable Ping block\n
+ * If the bit is it blocks the response to a ping request.
+ */
+#define MR_PB 0x10 ///< ping block
+
+/**
+ * @brief Enable PPPoE
+ * @details 0 : DisablePPPoE mode\n
+ * 1 : EnablePPPoE mode\n
+ * If you use ADSL, this bit should be '1'.
+ */
+#define MR_PPPOE 0x08 ///< enable pppoe
+
+/**
+ * @brief Address Auto-Increment in Indirect Bus Interface
+ * @details 0 : Disable auto-increment \n
+ * 1 : Enable auto-incremente \n
+ * At the Indirect Bus Interface mode, if this bit is set as �뜝�럩伊숂뙴�쉻�삕�뜝�룞�삕�넫濡レ쭢�뜝�룞�삕 the address will
+ * be automatically increased by 1 whenever read and write are performed.
+ */
+#define MR_AI 0x02 ///< auto-increment in indirect mode
+
+/**
+ * @brief Indirect Bus Interface mode
+ * @details 0 : Disable Indirect bus Interface mode \n
+ * 1 : Enable Indirect bus Interface mode \n
+ * If this bit is set as �뜝�럩伊숂뙴�쉻�삕�뜝�룞�삕�넫濡レ쭢�뜝�룞�삕 Indirect Bus Interface mode is set.
+ */
+#define MR_IND 0x01 ///< enable indirect mode
+
+/* IR register values */
+/**
+ * @brief Check IP conflict.
+ * @details Bit is set as when own source IP address is same with the sender IP address in the received ARP request.
+ */
+#define IR_CONFLICT 0x80 ///< check ip confict
+
+/**
+ * @brief Get the destination unreachable message in UDP sending.
+ * @details When receiving the ICMP (Destination port unreachable) packet, this bit is set as
+ * When this bit is Destination Information such as IP address and Port number may be checked with the corresponding @ref UIPR & @ref UPORTR.
+ */
+#define IR_UNREACH 0x40 ///< check destination unreachable
+
+/**
+ * @brief Get the PPPoE close message.
+ * @details When PPPoE is disconnected during PPPoE mode, this bit is set.
+ */
+#define IR_PPPoE 0x20 ///< get the PPPoE close message
+
+/**
+ * @brief Socket interrupt bit
+ * @details Indicates whether each socket interrupt has occured.
+ */
+#define IR_SOCK(sn) (0x01 << sn) ///< check socket interrupt
+
+/**
+ * @brief IP conflict interrupt mask bit
+ * @details If this bit is set, IP conflict interrupt is enabled.
+ */
+#define IMR_CONFLICT 0x80
+
+/**
+ * @brief Destination port unreachable interrupt mask bit
+ * @details If this bit is set, destination port unreachable interrupt is enabled.
+ */
+#define IMR_UNREACH 0x40
+
+/**
+ * @brief PADT/LCPT interrupt mask bit(PPPoE)
+ * @details If this bit is set, PADT/LCPT interrupt is enabled.
+ */
+#define IMR_PPPoE 0x20
+
+/**
+ * @brief Socket interrupt mask bit
+ * @details If this bit is set, each socket interrupt is enabled.
+ */
+#define IMR_SOCK(sn) (0x01 << sn)
+
+/**
+ * @brief Socket-less command register bit
+ * @details ARP command
+ */
+#define SLCMD_ARP (1<<1)
+
+/**
+ * @brief Socket-less command register bit
+ * @details ARP command
+ */
+#define SLCMD_PING (1<<0)
+
+/**
+ * @brief Socket-less command interrupt and interrupt mask register bit
+ * @details Request command time out interrupt and interrupt mask
+ */
+#define SLIR_TIMEOUT (1<<2)
+
+/**
+* @brief Socket less command interrupt and interrupt mask register bit
+* @details Socket less command ARP interrupt and interrupt mask
+*/
+#define SLIR_ARP (1<<1)
+
+/**
+* @brief Socket less command interrupt and interrupt mask register bit
+* @details Socket less command PING interrupt and interruptmask
+*/
+#define SLIR_PING (1<<0)
+
+
+
+// Sn_MR values
+/* Sn_MR Default values */
+/**
+ * @brief Unused socket
+ * @details This configures the protocol mode of Socket n.
+ */
+#define Sn_MR_CLOSE 0x00 ///< unused socket
+
+/**
+ * @brief TCP
+ * @details This configures the protocol mode of Socket n.
+ */
+#define Sn_MR_TCP 0x01 ///< TCP
+
+/**
+ * @brief UDP
+ * @details This configures the protocol mode of Socket n.
+ */
+#define Sn_MR_UDP 0x02 ///< UDP
+#define Sn_MR_IPRAW 0x03 ///< IP LAYER RAW SOCK
+
+/**
+ * @brief MAC LAYER RAW SOCK
+ * @details This configures the protocol mode of Socket n.
+ * @note MACRAW mode should be only used in Socket 0.
+ */
+#define Sn_MR_MACRAW 0x04 ///< MAC LAYER RAW SOCK
+
+/**
+ * @brief PPPoE
+ * @details This configures the protocol mode of Socket n.
+ * @note PPPoE mode should be only used in Socket 0.
+ */
+#define Sn_MR_PPPoE 0x05 ///< PPPoE
+
+/**
+ * @brief No Delayed Ack(TCP), Multicast flag
+ * @details 0 : Disable No Delayed ACK option\n
+ * 1 : Enable No Delayed ACK option\n
+ * This bit is applied only during TCP mode (P[3:0] = 001).\n
+ * When this bit is It sends the ACK packet without delay as soon as a Data packet is received from a peer.\n
+ * When this bit is It sends the ACK packet after waiting for the timeout time configured by \ref _RTR_.
+ */
+#define Sn_MR_ND 0x20 ///< No Delayed Ack(TCP) flag
+
+/**
+ * @brief Support UDP Multicasting
+ * @details 0 : using IGMP version 2\n
+ * 1 : using IGMP version 1\n
+ * This bit is applied only during UDP mode(P[3:0] = 010 and MULTI = '1')
+ * It configures the version for IGMP messages (Join/Leave/Report).
+ */
+#define Sn_MR_MC Sn_MR_ND ///< Select IGMP version 1(0) or 2(1)
+
+/**
+ * @brief MAC filter enable in @ref Sn_MR_MACRAW mode
+ * @details 0 : disable MAC Filtering\n
+ * 1 : enable MAC Filtering\n
+ * This bit is applied only during MACRAW mode(P[3:0] = 100.\n
+ * When set as W5100S can only receive broadcasting packet or packet sent to itself.
+ * When this bit is W5100S can receive all packets on Ethernet.
+ * If user wants to implement Hybrid TCP/IP stack,
+ * it is recommended that this bit is set as for reducing host overhead to process the all received packets.
+ */
+#define Sn_MR_MF 0x40 ///< Use MAC filter
+#define Sn_MR_MFEN Sn_MR_MF
+
+
+/* Sn_MR Default values */
+/**
+ * @brief Support UDP Multicasting
+ * @details 0 : disable Multicasting\n
+ * 1 : enable Multicasting\n
+ * This bit is applied only during UDP mode(P[3:0] = 010).\n
+ * To use multicasting, \ref Sn_DIPR & \ref Sn_DPORT should be respectively configured with the multicast group IP address & port number
+ * before Socket n is opened by OPEN command of \ref Sn_CR.
+ */
+#define Sn_MR_MULTI 0x80 ///< support multicating
+
+/* Sn_CR values */
+/**
+ * @brief Initialize or open socket
+ * @details Socket n is initialized and opened according to the protocol selected in Sn_MR(P3:P0).
+ * The table below shows the value of \ref Sn_SR corresponding to \ref Sn_MR.\n
+ *
+ *
\b Sn_MR (P[3:0])
\b Sn_SR
+ *
Sn_MR_CLOSE (000)
--
+ *
Sn_MR_TCP (001)
SOCK_INIT (0x13)
+ *
Sn_MR_UDP (010)
SOCK_UDP (0x22)
+ *
S0_MR_IPRAW (011)
SOCK_IPRAW (0x32)
+ *
S0_MR_MACRAW (100)
SOCK_MACRAW (0x42)
+ *
S0_MR_PPPoE (101)
SOCK_PPPoE (0x5F)
+ *
+ */
+#define Sn_CR_OPEN 0x01 ///< initialize or open socket
+
+/**
+ * @brief Wait connection request in TCP mode(Server mode)
+ * @details This is valid only in TCP mode (Sn_MR(P3:P0) = \ref Sn_MR_TCP).//
+ * In this mode, Socket n operates as a 'TCP server' and waits for connection-request (SYN packet) from any 'TCP client'.//
+ * The \ref Sn_SR changes the state from SOCK_INIT to SOCKET_LISTEN.//
+ * When a 'TCP client' connection request is successfully established,
+ * the \ref Sn_SR changes from SOCK_LISTEN to SOCK_ESTABLISHED and the Sn_IR(0) becomes
+ * But when a 'TCP client' connection request is failed, Sn_IR(3) becomes and the status of \ref Sn_SR changes to SOCK_CLOSED.
+ */
+#define Sn_CR_LISTEN 0x02 ///< wait connection request in tcp mode(Server mode)
+
+/**
+ * @brief Send connection request in TCP mode(Client mode)
+ * @details To connect, a connect-request (SYN packet) is sent to TCP serverconfigured by \ref Sn_DIPR & Sn_DPORT(destination address & port).
+ * If the connect-request is successful, the \ref Sn_SR is changed to \ref SOCK_ESTABLISHED and the Sn_IR(0) becomes \n\n
+ * The connect-request fails in the following three cases.\n
+ * 1. When a @b ARPTO occurs (\ref Sn_IR[3] = '1') because destination hardware address is not acquired through the ARP-process.\n
+ * 2. When a @b SYN/ACK packet is not received and @b TCPTO (Sn_IR(3) ='1')\n
+ * 3. When a @b RST packet is received instead of a @b SYN/ACK packet. In these cases, \ref Sn_SR is changed to \ref SOCK_CLOSED.
+ * @note This is valid only in TCP mode and operates when Socket n acts as TCP client
+ */
+#define Sn_CR_CONNECT 0x04 ///< send connection request in tcp mode(Client mode)
+
+/**
+ * @brief Send closing request in TCP mode
+ * @details Regardless of TCP serveror TCP client the DISCON command processes the disconnect-process (Active closeor Passive close.\n
+ * @par Active close
+ * it transmits disconnect-request(FIN packet) to the connected peer\n
+ * @par Passive close
+ * When FIN packet is received from peer, a FIN packet is replied back to the peer.\n
+ * @details When the disconnect-process is successful (that is, FIN/ACK packet is received successfully), \ref Sn_SR is changed to \ref SOCK_CLOSED.\n
+ * Otherwise, TCPTO occurs (Sn_IR(3)='1') and then \ref Sn_SR is changed to \ref SOCK_CLOSED.
+ * @note Valid only in TCP mode.
+ */
+#define Sn_CR_DISCON 0x08 ///< send closing reqeuset in tcp mode
+
+/**
+ * @brief Close socket
+ * @details Sn_SR is changed to \ref SOCK_CLOSED.
+ */
+#define Sn_CR_CLOSE 0x10
+
+/**
+ * @brief Update TX buffer pointer and send data
+ * @details SEND transmits all the data in the Socket n TX buffer.\n
+ * For more details, please refer to Socket n TX Free Size Register (\ref Sn_TX_FSR), Socket n,
+ * TX Write Pointer Register(\ref Sn_TX_WR), and Socket n TX Read Pointer Register(\ref Sn_TX_RD).
+ */
+#define Sn_CR_SEND 0x20
+
+/**
+ * @brief Send data with MAC address, so without ARP process
+ * @details The basic operation is same as SEND.\n
+ * Normally SEND transmits data after destination hardware address is acquired by the automatic ARP-process(Address Resolution Protocol).\n
+ * But SEND_MAC transmits data without the automatic ARP-process.\n
+ * In this case, the destination hardware address is acquired from \ref Sn_DHAR configured by host, instead of APR-process.
+ * @note Valid only in UDP mode.
+ */
+#define Sn_CR_SEND_MAC 0x21
+
+/**
+ * @brief Send keep alive message
+ * @details It checks the connection status by sending 1byte keep-alive packet.\n
+ * If the peer can not respond to the keep-alive packet during timeout time, the connection is terminated and the timeout interrupt will occur.
+ * @note Valid only in TCP mode.
+ */
+#define Sn_CR_SEND_KEEP 0x22
+
+/**
+ * @brief Update RX buffer pointer and receive data
+ * @details RECV completes the processing of the received data in Socket n RX Buffer by using a RX read pointer register (\ref Sn_RX_RD).\n
+ * For more details, refer to Socket n RX Received Size Register (\ref Sn_RX_RSR), Socket n RX Write Pointer Register (\ref Sn_RX_WR),
+ * and Socket n RX Read Pointer Register (\ref Sn_RX_RD).
+ */
+#define Sn_CR_RECV 0x40
+
+/**
+ * @brief
+ * @details
+ */
+#define Sn_CR_IGMP_JOIN 0x23
+
+/**
+ * @brief
+ * @details
+ */
+#define Sn_CR_IGMP_LEAVE 0x24
+
+
+/* Sn_IR values */
+
+/**
+ * @brief SEND_OK Interrupt
+ * @details This is issued when SEND command is completed.
+ */
+#define Sn_IR_SENDOK 0x10 ///< complete sending
+
+/**
+ * @brief TIMEOUT Interrupt
+ * @details This is issued when ARPTO or TCPTO occurs.
+ */
+#define Sn_IR_TIMEOUT 0x08 ///< assert timeout
+
+/**
+ * @brief RECV Interrupt
+ * @details This is issued whenever data is received from a peer.
+ */
+#define Sn_IR_RECV 0x04
+
+/**
+ * @brief DISCON Interrupt
+ * @details This is issued when FIN or FIN/ACK packet is received from a peer.
+ */
+#define Sn_IR_DISCON 0x02
+
+/**
+ * @brief CON Interrupt
+ * @details This is issued one time when the connection with peer is successful and then \ref Sn_SR is changed to \ref SOCK_ESTABLISHED.
+ */
+#define Sn_IR_CON 0x01
+
+/* Sn_SR values */
+/**
+ * @brief Closed
+ * @details This indicates that Socket n is released.\n
+ * When DICON, CLOSE command is ordered, or when a timeout occurs, it is changed to \ref SOCK_CLOSED regardless of previous status.
+ */
+#define SOCK_CLOSED 0x00 ///< closed
+
+/**
+ * @brief Initiate state
+ * @details This indicates Socket n is opened with TCP mode.\n
+ * It is changed to \ref SOCK_INIT when Sn_MR(P[3:0]) = 001)and OPEN command is ordered.\n
+ * After \ref SOCK_INIT, user can use LISTEN /CONNECT command.
+ */
+#define SOCK_INIT 0x13 ///< init state
+
+/**
+ * @brief Listen state
+ * @details This indicates Socket n is operating as TCP servermode and waiting for connection-request (SYN packet) from a peer (TCP client).\n
+ * It will change to \ref SOCK_ESTABLISHED when the connection-request is successfully accepted.\n
+ * Otherwise it will change to \ref SOCK_CLOSED after TCPTO occurred (Sn_IR(TIMEOUT) = '1').
+ */
+#define SOCK_LISTEN 0x14
+
+/**
+ * @brief Connection state
+ * @details This indicates Socket n sent the connect-request packet (SYN packet) to a peer.\n
+ * It is temporarily shown when \ref Sn_SR is changed from \ref SOCK_INIT to \ref SOCK_ESTABLISHED by CONNECT command.\n
+ * If connect-accept(SYN/ACK packet) is received from the peer at SOCK_SYNSENT, it changes to \ref SOCK_ESTABLISHED.\n
+ * Otherwise, it changes to \ref SOCK_CLOSED after TCPTO (\ref Sn_IR[TIMEOUT] = '1') is occurred.
+ */
+#define SOCK_SYNSENT 0x15
+
+/**
+ * @brief Connection state
+ * @details It indicates Socket n successfully received the connect-request packet (SYN packet) from a peer.\n
+ * If socket n sends the response (SYN/ACK packet) to the peer successfully, it changes to \ref SOCK_ESTABLISHED. \n
+ * If not, it changes to \ref SOCK_CLOSED after timeout occurs (\ref Sn_IR[TIMEOUT] = '1').
+ */
+#define SOCK_SYNRECV 0x16
+
+/**
+ * @brief Success to connect
+ * @details This indicates the status of the connection of Socket n.\n
+ * It changes to \ref SOCK_ESTABLISHED when the TCP SERVERprocessed the SYN packet from the TCP CLIENTduring \ref SOCK_LISTEN, or
+ * when the CONNECT command is successful.\n
+ * During \ref SOCK_ESTABLISHED, DATA packet can be transferred using SEND or RECV command.
+ */
+#define SOCK_ESTABLISHED 0x17
+
+/**
+ * @brief Closing state
+ * @details These indicate Socket n is closing.\n
+ * These are shown in disconnect-process such as active-close and passive-close.\n
+ * When Disconnect-process is successfully completed, or when timeout occurs, these change to \ref SOCK_CLOSED.
+ */
+#define SOCK_FIN_WAIT 0x18
+
+/**
+ * @brief Closing state
+ * @details These indicate Socket n is closing.\n
+ * These are shown in disconnect-process such as active-close and passive-close.\n
+ * When Disconnect-process is successfully completed, or when timeout occurs, these change to \ref SOCK_CLOSED.
+ */
+#define SOCK_CLOSING 0x1A
+
+/**
+ * @brief Closing state
+ * @details These indicate Socket n is closing.\n
+ * These are shown in disconnect-process such as active-close and passive-close.\n
+ * When Disconnect-process is successfully completed, or when timeout occurs, these change to \ref SOCK_CLOSED.
+ */
+#define SOCK_TIME_WAIT 0x1B
+
+/**
+ * @brief Closing state
+ * @details This indicates Socket n received the disconnect-request (FIN packet) from the connected peer.\n
+ * This is half-closing status, and data can be transferred.\n
+ * For full-closing, DISCON command is used. But For just-closing, @ref Sn_CR_CLOSE command is used.
+ */
+#define SOCK_CLOSE_WAIT 0x1C
+
+/**
+ * @brief Closing state
+ * @details This indicates Socket n is waiting for the response (FIN/ACK packet) to the disconnect-request (FIN packet) by passive-close.\n
+ * It changes to \ref SOCK_CLOSED when Socket n received the response successfully, or when timeout occurs (\ref Sn_IR[TIMEOUT] = '1').
+ */
+#define SOCK_LAST_ACK 0x1D
+
+/**
+ * @brief UDP socket
+ * @details This indicates Socket n is opened in UDP mode(Sn_MR(P[3:0]) = 010).\n
+ * It changes to SOCK_UDP when Sn_MR(P[3:0]) = 010 and @ref Sn_CR_OPEN command is ordered.\n
+ * Unlike TCP mode, data can be transfered without the connection-process.
+ */
+#define SOCK_UDP 0x22 ///< udp socket
+
+/**
+ * @brief IP raw mode socket
+ * @details TThe socket is opened in IPRAW mode. The SOCKET status is change to SOCK_IPRAW when @ref Sn_MR (P3:P0) is
+ * Sn_MR_IPRAW and @ref Sn_CR_OPEN command is used.\n
+ * IP Packet can be transferred without a connection similar to the UDP mode.
+*/
+#define SOCK_IPRAW 0x32 ///< ip raw mode socket
+
+/**
+ * @brief MAC raw mode socket
+ * @details This indicates Socket 0 is opened in MACRAW mode (@ref Sn_MR(P[3:0]) = '100' and n=0) and is valid only in Socket 0.\n
+ * It changes to SOCK_MACRAW when @ref Sn_MR(P[3:0]) = '100' and @ref Sn_CR_OPEN command is ordered.\n
+ * Like UDP mode socket, MACRAW mode Socket 0 can transfer a MAC packet (Ethernet frame) without the connection-process.
+ */
+#define SOCK_MACRAW 0x42 ///< mac raw mode socket
+
+/**
+ * @brief PPPoE mode socket
+ * @details It is the status that SOCKET0 is open as PPPoE mode. It is changed to SOCK_PPPoE in case of S0_CR=OPEN and S0_MR
+ * (P3:P0)=S0_MR_PPPoE.\n
+ * It is temporarily used at the PPPoE
+connection.
+ */
+#define SOCK_PPPOE 0x5F ///< pppoe socket
+
+// IP PROTOCOL
+#define IPPROTO_IP 0 ///< Dummy for IP
+#define IPPROTO_ICMP 1 ///< Control message protocol
+#define IPPROTO_IGMP 2 ///< Internet group management protocol
+#define IPPROTO_GGP 3 ///< GW^2 (deprecated)
+#define IPPROTO_TCP 6 ///< TCP
+#define IPPROTO_PUP 12 ///< PUP
+#define IPPROTO_UDP 17 ///< UDP
+#define IPPROTO_IDP 22 ///< XNS idp
+#define IPPROTO_ND 77 ///< UNOFFICIAL net disk protocol
+#define IPPROTO_RAW 255 ///< Raw IP packet
+
+
+
+/*----------------------------- W5100S !!Only!! Register values -----------------------------*/
+
+//todo
+/* MODE2 register values */
+
+/**
+ * @brief Clock select bit
+ * @details With this bit, system clock can be selected to be 25Mhz or 100Mhz
+ * 1: 25Mhz
+ * 0: 100Mhz (default)
+ */
+#define MR2_CLKSEL (1<<7)
+
+/**
+ * @brief Interrupt pin enable bit
+ * @details This bit enables interrupt.
+ * 1: Enable interrupt
+ * 0: Disable interrupt
+ */
+#define MR2_G_IEN (1<<6)
+
+
+/**
+ * @brief No TCP Reset Packet send
+ * @details This bit prevents sending reset packet.
+ * 1: Block TCP reset packet send
+ * 0: TCP Reset packet send
+ */
+#define MR2_NOTCPRST (1<<5)
+
+/**
+ * @brief Unreachable Packet Send Block bit
+ * @details This bit prevents sending Destination Port Unreachable Packet.
+ * 1: Block Destination Port Unreachable Packet Send
+ * 0: Destination Port Unreachable Packet Send
+ */
+#define MR2_UDPURB (1<<4)
+
+/**
+ * @brief Wake On LAN
+ * @details This bit enables WOL packet to be received.
+ * 1: WOL packet can be received.
+ * 0: WOL packet cannot be received.
+ */
+#define MR2_WOL (1<<3)
+
+/**todo
+ * @brief MACRAW No Size Check
+ * @details
+ */
+#define MR2_MNOSCHK (1<<2)
+
+/**
+ * @brief UDP force ARP
+ * @details This bit can enables to force ARP for each send command.
+ * 1: UDP Force ARP Enable
+ * 0: UDP Force ARP Disable.
+ *
+ */
+#define MR2_UDPFARP (1<<1)
+
+/**todo
+ * @brief Skip SRC Hardware Address
+ * @details This bit can enables to receive without checking the hardware address of the peer.
+ * 1:
+ */
+#define MR2_SSRCHA (1<<0)
+
+
+
+/* Common interrupt register 2 values */
+
+/**todo
+ * @brief magic packet
+ * @details
+ */
+#define IR2_MGC (1<<1)
+
+/**todo
+ * @brief Magic packet interrupt mask bit
+ * @details If this bit is set, each socket interrupt is enabled.
+ */
+#define IMR2_MGC (1<<1)
+
+/**todo
+ * @brief
+ * @details
+ */
+//#define IR2_MGD (1<<1) /* Reserved */
+
+
+/* PHY status register 0 values */
+
+/**todo
+ * @brief Ethernet CABLE OFF Signal
+ * @details
+ */
+#define PHYSR_CABOFF (1<<7)
+
+/**todo
+ * @brief
+ * @details
+ */
+#define PHYSR_MD2 (1<<5)
+
+/**todo
+ * @brief
+ * @details
+ */
+#define PHYSR_MD1 (1<<4)
+
+/**todo
+ * @brief
+ * @details
+ */
+#define PHYSR_MD0 (1<<3)
+
+/**todo
+ * @brief
+ * @details
+ */
+#define PHYSR_DUP (1<<2)
+
+/**todo
+ * @brief
+ * @details
+ */
+#define PHYSR_SPD (1<<1)
+
+/**todo
+ * @brief LINKDONE register
+ * @details If 1 Linked successfully, if 0 no link
+ */
+#define PHYSR_LNK (1<<0)
+
+
+/* PHY status register 10 values */
+
+/**
+ * @brieftodo
+ * @details
+ */
+#define PHYSR1_RXPG (1<<2)
+
+/**
+ * @brieftodo
+ * @details
+ */
+#define PHYSR1_LPI (1<<1)
+
+/**
+ * @brieftodo
+ * @details
+ */
+#define PHYSR1_CLDN (1<<0)
+
+#define PHYCR_AUTONEGO_ENABLE (0<<2)
+#define PHYCR_AUTONEGO_DISABLE (1<<2)
+
+#define PHYCR_SPD_10 (1<<1)
+#define PHYCR_SPD_100 (0<<1)
+
+#define PHYCR_HALF_DUP (1<<0)
+#define PHYCR_FULL_DUP (0<<0)
+
+#define PHYCR1_RST (0<<0)
+
+#define PHYCR1_PWDN_ENABLE (1<<5)
+#define PHYCR1_PWDN_DISABLE (0<<5)
+
+
+/* Socket n MODE register 2 values */
+
+/**
+ * @brief Broadcast Blocking bit in MACRAW mode
+ * @details In MACRAW mode, this bit is set to ????to block the broadcast packet.
+ */
+#define Sn_MR2_MBBLK (1<<6)
+
+/**
+ * @brief Multicast Blocking bit in MACRAW mode
+ * @details In MACRAW mode, this bit is set to ????to block the multicast packet.
+ */
+#define Sn_MR2_MMBLK (1<<5)
+
+/**
+ * @brief IPv6 packet Blocking bit in MACRAW mode
+ * @details In MACRAW mode, this bit is set to ????to block the IPv6 packet.
+ */
+#define Sn_MR2_IPV6BLK (1<<4)
+
+
+/**
+ * @brief Broadcast Blocking bit in UDP mode
+ * @details In UDP mode, this bit is set to ????to block the broadcast packet.
+ */
+#define Sn_MR2_UBBLK (1<<1)
+
+
+/**
+ * @brief TCP Force PSH bit
+ * @details When the SOCKET transmits data in TCP mode, PSH Flag is set to all packets.
+ */
+#define Sn_MR2_FPSH Sn_MR2_UBBLK
+
+/**
+ * @brief Unicast Blocking bit in UDP mode
+ * @details In UDP mode, this bit is set to ????to block the Unicast packet.
+ */
+#define Sn_MR2_UUBLK (1<<0)
+
+/*----------------------------For PHY Control-------------------------------*/
+
+/********************/
+/* Register Address */
+/********************/
+
+//Basic mode control register, basic register
+#define PHYMDIO_BMCR 0x00
+
+//Basic mode status register, basic register
+#define PHYMDIO_BMSR 0x01
+
+//--------------------------------------Not used-------------------------------------------//
+////PHY identifier register 1, extended register
+//#define PHY_IDR1 0x02 //not used
+//
+////PHY identifier register 2, extended register
+//#define PHY_IDR2 0x03 //not used
+//
+////Auto-negotiation advertisement register, extended register
+//#define PHY_ANAR 0x04 //not used
+//
+////Auto-negotiation link partner ability register, extended register
+//#define PHY_ANLPAR 0x05 //not used
+//
+////Auto-negotiation expansion register, extended register
+//#define PHY_ANER 0x06 //not used
+//
+////Auto-negotiation next page transmit
+//#define PHY_ANNP 0x07 //not used
+//
+////Auto-negotiation link partner of the next page receive
+//#define PHY_ANLPNP 0x08 //not used
+//
+////MMD access control register
+//#define PHY_REGCR 0x09 //not used
+//
+////MMD access address data register
+//#define PHY_ADDAR 0x0e //not used
+//--------------------------------------Not used-------------------------------------------//
+
+/********************/
+/* Bit definitions */
+/********************/
+
+//For BMCR register
+#define BMCR_RESET (1<<15)
+#define BMCR_MLOOPBACK (1<<14)
+#define BMCR_SPEED (1<<13)
+#define BMCR_AUTONEGO (1<<12)
+#define BMCR_PWDN (1<<11)
+#define BMCR_ISOLATE (1<<10)
+#define BMCR_RSTNEGO (1<<9)
+#define BMCR_DUP (1<<8)
+#define BMCR_COLTEST (1<<7)
+
+//For BMSR register
+#define BMSR_AUTONEGO_COMPL (1<<5)
+#define BMSR_REMOTE_FAULT (1<<4)
+#define BMSR_LINK_STATUS (1<<2)
+#define BMSR_JAB_DETECT (1<<1)
+#define EXTENDED_CAPA (1<<0)
+
+//--------------------------------------Not used-------------------------------------------//
+////For ANAR register
+//#define ANAR_NP (1<<15)
+//#define ANAR_ACK (1<<14)
+//#define ANAR_RF (1<<13)
+//#define ANAR_ASM (3<<10)
+//#define ANAR_T4 (1<<9)
+//#define ANAR_TX_FD (1<<8)
+//#define ANAR_TX_HD (1<<7)
+//#define ANAR_10_FD (1<<6)
+//#define ANAR_10_HD (1<<5)
+//#define ANAR_SELECTOR (0x1F<<0)
+//
+////For ANAR register
+//#define ANLPAR_NP (1<<15)
+//#define ANLPAR_ACK (1<<14)
+//#define ANLPAR_RF (1<<13)
+//#define ANLPAR_LP_DIR (1<<11)
+//#define ANLPAR_PAUSE (1<<10)
+//#define ANLPAR_T4 (1<<9)
+//#define ANLPAR_TX_FD (1<<8)
+//#define ANLPAR_TX_HD (1<<7)
+//#define ANLPAR_10_FD (1<<6)
+//#define ANLPAR_10_HD (1<<5)
+//#define ANLPAR_SELECTOR (0x1F<<0)
+
+/**/
+/* MDIO register*/
+//PCS_CTL_1 | PCS control 1 register
+//PCS_STS_1 | PCS status 1 register
+//EEE_ABILITY | EEE capability register
+//WAKE_ER_CNTR | EEE wake error counter
+//EEE_ADVR | EEE Advertisement register
+//EEE_LPAR | EEE link partner ability register
+
+//--------------------------------------Not used-------------------------------------------//
+
+/********************/
+/*Functions for PHY */
+/********************/
+//todo move this definition to bit area
+#define PHYACR_READ 0x02
+#define PHYACR_WRITE 0x01
+
+
+
+
+/**
+ * @brief Enter a critical section
+ *
+ * @details It is provided to protect your shared code which are executed without distribution. \n \n
+ *
+ * In non-OS environment, It can be just implemented by disabling whole interrupt.\n
+ * In OS environment, You can replace it to critical section api supported by OS.
+ *
+ * \sa WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF()
+ * \sa WIZCHIP_CRITICAL_EXIT()
+ */
+#define WIZCHIP_CRITICAL_ENTER() WIZCHIP.CRIS._enter()
+
+#ifdef _exit
+#undef _exit
+#endif
+
+/**
+ * @brief Exit a critical section
+ *
+ * @details It is provided to protect your shared code which are executed without distribution. \n\n
+ *
+ * In non-OS environment, It can be just implemented by disabling whole interrupt. \n
+ * In OS environment, You can replace it to critical section api supported by OS.
+ *
+ * @sa WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF()
+ * @sa WIZCHIP_CRITICAL_ENTER()
+ */
+#define WIZCHIP_CRITICAL_EXIT() WIZCHIP.CRIS._exit()
+
+
+
+////////////////////////
+// Basic I/O Function //
+////////////////////////
+//
+//M20150601 : uint16_t AddrSel --> uint32_t AddrSel
+//
+/**
+ * @ingroup Basic_IO_function_W5100S
+ * @brief It reads 1 byte value from a register.
+ * @param AddrSel Register address
+ * @return The value of register
+ */
+uint8_t WIZCHIP_READ (uint32_t AddrSel);
+
+/**
+ * @ingroup Basic_IO_function_W5100S
+ * @brief It writes 1 byte value to a register.
+ * @param AddrSel Register address
+ * @param wb Write data
+ * @return void
+ */
+void WIZCHIP_WRITE(uint32_t AddrSel, uint8_t wb );
+
+/**
+ * @ingroup Basic_IO_function_W5100S
+ * @brief It reads sequence data from registers.
+ * @param AddrSel Register address
+ * @param pBuf Pointer buffer to read data
+ * @param len Data length
+ */
+void WIZCHIP_READ_BUF (uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
+
+/**
+ * @ingroup Basic_IO_function_W5100S
+ * @brief It writes sequence data to registers.
+ * @param AddrSel Register address
+ * @param pBuf Pointer buffer to write data
+ * @param len Data length
+ */
+void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
+
+
+/////////////////////////////////
+// Common Register IO function //
+/////////////////////////////////
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set Mode Register
+ * @param (uint8_t)mr The value to be set.
+ * @sa getMR()
+ */
+#if (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_)
+ #define setMR(mr) WIZCHIP_WRITE(MR,mr)
+#else
+ #define setMR(mr) (*((uint8_t*)MR) = mr)
+#endif
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get @ref MR.
+ * @return uint8_t. The value of Mode register.
+ * @sa setMR()
+ */
+#if (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_)
+ #define getMR() WIZCHIP_READ(MR)
+#else
+ #define getMR() (*(uint8_t*)MR)
+#endif
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set @ref GAR.
+ * @param (uint8_t*)gar Pointer variable to set gateway IP address. It should be allocated 4 bytes.
+ * @sa getGAR()
+ */
+#define setGAR(gar) \
+ WIZCHIP_WRITE_BUF(GAR,gar,4)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get @ref GAR.
+ * @param (uint8_t*)gar Pointer variable to get gateway IP address. It should be allocated 4 bytes.
+ * @sa setGAR()
+ */
+#define getGAR(gar) \
+ WIZCHIP_READ_BUF(GAR,gar,4)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set @ref SUBR.
+ * @param (uint8_t*)subr Pointer variable to set subnet mask address. It should be allocated 4 bytes.
+ * @note If subr is null pointer, set the backup subnet to SUBR. \n
+ * If subr is 0.0.0.0, back up SUBR and clear it. \n
+ * Otherwize, set subr to SUBR
+ * @sa getSUBR()
+ */
+#define setSUBR(subr) \
+ WIZCHIP_WRITE_BUF(SUBR,subr,4)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get @ref SUBR.
+ * @param (uint8_t*)subr Pointer variable to get subnet mask address. It should be allocated 4 bytes.
+ * @sa setSUBR()
+ */
+#define getSUBR(subr) \
+ WIZCHIP_READ_BUF(SUBR, subr, 4)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set @ref SHAR.
+ * @param (uint8_t*)shar Pointer variable to set local MAC address. It should be allocated 6 bytes.
+ * @sa getSHAR()
+ */
+#define setSHAR(shar) \
+ WIZCHIP_WRITE_BUF(SHAR, shar, 6)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get @ref SHAR.
+ * @param (uint8_t*)shar Pointer variable to get local MAC address. It should be allocated 6 bytes.
+ * @sa setSHAR()
+ */
+#define getSHAR(shar) \
+ WIZCHIP_READ_BUF(SHAR, shar, 6)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set @ref SIPR.
+ * @param (uint8_t*)sipr Pointer variable to set local IP address. It should be allocated 4 bytes.
+ * @sa getSIPR()
+*/
+#define setSIPR(sipr) \
+ WIZCHIP_WRITE_BUF(SIPR, sipr, 4)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get @ref SIPR.
+ * @param (uint8_t*)sipr Pointer variable to get local IP address. It should be allocated 4 bytes.
+ * @sa setSIPR()
+ */
+#define getSIPR(sipr) \
+ WIZCHIP_READ_BUF(SIPR, sipr, 4)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref IR register
+ * @param (uint8_t)ir Value to set \ref IR register.
+ * @sa getIR()
+ */
+#define setIR(ir) \
+ WIZCHIP_WRITE(IR, (ir & 0xE0)) //peter 2016.11.07 unreachable interrupt bit added
+ //WIZCHIP_WRITE(IR, (ir & 0xA0))
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref IR register
+ * @return uint8_t. Value of \ref IR register.
+ * @sa setIR()
+ */
+#define getIR() \
+ (WIZCHIP_READ(IR) & 0xE0) //peter 2016.11.07 unreachable interrupt bit added
+ //(WIZCHIP_READ(IR) & 0xA0)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref _IMR_ register
+ * @param (uint8_t)imr Value to set @ref _IMR_ register.
+ * @sa getIMR()
+ */
+#define setIMR(imr) \
+ WIZCHIP_WRITE(_IMR_, imr)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref _IMR_ register
+ * @return uint8_t. Value of @ref _IMR_ register.
+ * @sa setIMR()
+ */
+#define getIMR() \
+ WIZCHIP_READ(_IMR_)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref _RTR_ register
+ * @param (uint16_t)rtr Value to set @ref _RTR_ register.
+ * @sa getRTR()
+ */
+#define setRTR(rtr) {\
+ WIZCHIP_WRITE(_RTR_, (uint8_t)(rtr >> 8)); \
+ WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(_RTR_,1), (uint8_t) rtr); \
+ }
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref _RTR_ register
+ * @return uint16_t. Value of @ref _RTR_ register.
+ * @sa setRTR()
+ */
+#define getRTR() \
+ (((uint16_t)WIZCHIP_READ(_RTR_) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(_RTR_,1)))
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref _RCR_ register
+ * @param (uint8_t)rcr Value to set @ref _RCR_ register.
+ * @sa getRCR()
+ */
+#define setRCR(rcr) \
+ WIZCHIP_WRITE(_RCR_, rcr)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref _RCR_ register
+ * @return uint8_t. Value of @ref _RCR_ register.
+ * @sa setRCR()
+ */
+#define getRCR() \
+ WIZCHIP_READ(_RCR_)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref RMSR register
+ * @sa getRMSR()
+ */
+#define setRMSR(rmsr) \
+ WIZCHIP_WRITE(RMSR,rmsr) // Receicve Memory Size
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref RMSR register
+ * @return uint8_t. Value of @ref RMSR register.
+ * @sa setRMSR()
+ */
+ #define getRMSR() \
+ WIZCHIP_READ(RMSR) // Receicve Memory Size
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref TMSR register
+ * @sa getTMSR()
+ */
+#define setTMSR(tmsr) \
+ WIZCHIP_WRITE(TMSR,tmsr) // Receicve Memory Size
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref TMSR register
+ * @return uint8_t. Value of @ref TMSR register.
+ * @sa setTMSR()
+ */
+#define getTMSR() \
+ WIZCHIP_READ(TMSR)
+
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref PATR register
+ * @return uint16_t. Value to set \ref PATR register
+ */
+#define getPATR() \
+ (((uint16_t)WIZCHIP_READ(PATR) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(PATR,1)))
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref PPPALGO register
+ * @return uint8_t. Value to set \ref PPPALGO register
+ */
+#define getPPPALGO() \
+ WIZCHIP_READ(PPPALGO)
+
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref PTIMER register
+ * @param (uint8_t)ptimer Value to set \ref PTIMER register.
+ * @sa getPTIMER()
+ */
+#define setPTIMER(ptimer) \
+ WIZCHIP_WRITE(PTIMER, ptimer)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref PTIMER register
+ * @return uint8_t. Value of @ref PTIMER register.
+ * @sa setPTIMER()
+ */
+#define getPTIMER() \
+ WIZCHIP_READ(PTIMER)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref PMAGIC register
+ * @param (uint8_t)pmagic Value to set @ref PMAGIC register.
+ * @sa getPMAGIC()
+ */
+#define setPMAGIC(pmagic) \
+ WIZCHIP_WRITE(PMAGIC, pmagic)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref PMAGIC register
+ * @return uint8_t. Value of @ref PMAGIC register.
+ * @sa setPMAGIC()
+ */
+#define getPMAGIC() \
+ WIZCHIP_READ(PMAGIC)
+
+
+//todo Functions for W5100S
+
+/*----------------------------------------------------------------------*/
+/* W5100S only */
+/*----------------------------------------------------------------------*/
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref IR2 register
+ * @param (uint8_t)ir2 Value to set @ref IR2 register.
+ * @sa getIR2()
+ */
+#define setIR2(ir2) \
+ WIZCHIP_WRITE(IR2, ir2)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref IR2 register
+ * @return uint8_t. Value of @ref IR2 register.
+ * @sa setIR2()
+ */
+#define getIR2() \
+ WIZCHIP_READ(IR2)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref IMR2 register
+ * @param (uint8_t)imr2 Value to set @ref IMR2 register.
+ * @sa setIMR2()
+ */
+#define setIMR2(imr2) \
+ WIZCHIP_WRITE(IMR2,imr2)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref IMR2 register
+ * @return uint8_t. Value of @ref IMR2 register.
+ * @sa getIMR2()
+ */
+#define getIMR2() \
+ WIZCHIP_READ(IMR2)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref UIPR(Unreachable IP Address Register) registers
+ * @param (uint8_t*)uipr Value to set @ref UIPR registers.
+ * @sa setUIPR()
+ */
+#define setUIPR(uipr) \
+ WIZCHIP_WRITE_BUF(UIPR,uipr,4)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref UIPR(Unreachable IP Address Register) registers
+ * @param (uint8_t*)uipr Value to get @ref UIPR registers
+ * @sa setUIPR()
+ */
+#define getUIPR(uipr) \
+ WIZCHIP_READ_BUF(UIPR,uipr,4)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref UPORTR(Unreachable Port Address Register) register
+ * @param (uint16_t)uportr Value to set @ref UPORTR register.
+ * @sa getUPORTR()
+ */
+#define setUPORTR(uportr) {\
+ WIZCHIP_WRITE(UPORTR, (uint8_t)(uportr >> 8)); \
+ WIZCHIP_WRITE(UPORTR+1, (uint8_t) uportr); \
+ }
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref UPORTR(Unreachable Port Address Register) register
+ * @return uint16_t. Value of @ref UPORTR register.
+ * @sa setUPORTR()
+ */
+#define getUPORTR() \
+ (((uint16_t)WIZCHIP_READ(UPORTR) << 8) + WIZCHIP_READ(UPORTR+1))
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref MR2 register
+ * @param (uint8_t)mr2 Value to set @ref MR2 registers.
+ * @sa getMR2()
+ */
+#define setMR2(mr2) \
+ WIZCHIP_WRITE(MR2,mr2)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref MR2 register
+ * @return uint8_t. Value of @ref MR2 register.
+ * @sa setMR2()
+ */
+#define getMR2() \
+ WIZCHIP_READ(MR2)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref PHAR registers
+ * @param (uint8_t*)phar Value to set @ref PHAR registers.
+ * @sa getPHAR()
+ */
+#define setPHAR(phar) \
+ WIZCHIP_WRITE_BUF(PHAR,phar,6)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref PHAR registers
+ * @param (uint8_t*)phar Pointer variable to get @ref PHAR registers.
+ * @sa setPHAR()
+ */
+#define getPHAR(phar) \
+ WIZCHIP_READ_BUF(PHAR,phar,6)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref PSIDR register
+ * @param (uint16_t)psidr Value to set @ref PSIDR register.
+ * @sa getPSIDR()
+ */
+#define setPSIDR(psidr) {\
+ WIZCHIP_WRITE(PSIDR, (uint8_t)(psidr >> 8)); \
+ WIZCHIP_WRITE(PSIDR+1, (uint8_t) psidr); \
+ }
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref PSIDR register
+ * @return uint16_t. Value of @ref PSIDR register.
+ * @sa setPSIDR()
+ */
+#define getPSIDR() \
+ (((uint16_t)WIZCHIP_READ(PSIDR) << 8) + WIZCHIP_READ(PSIDR+1))
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref PMRUR register
+ * @param (uint16_t)pmrur Value to set @ref PMRUR register.
+ * @sa getPMRUR()
+ */
+#define setPMRUR(pmrur) {\
+ WIZCHIP_WRITE(PMRUR, (uint8_t)(pmrur >> 8)); \
+ WIZCHIP_WRITE(PMRUR+1, (uint8_t) pmrur); \
+ }
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref PMRUR register
+ * @return uint16_t. Value of @ref PMRUR register.
+ * @sa setPMRUR()
+ */
+#define getPMRUR() \
+ (((uint16_t)WIZCHIP_READ(PMRUR) << 8) + WIZCHIP_READ(PMRUR+1))
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref PHYSR register
+ * @return uint8_t. Value of @ref PHYSR register.
+ * @sa setPHYSR()
+ */
+#define getPHYSR() \
+ WIZCHIP_READ(PHYSR)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref PHYSR1 register
+ * @return uint8_t. Value of @ref PHYSR1 register.
+ * @sa setPHYSR1()
+ */
+#define getPHYSR1() \
+ WIZCHIP_READ(PHYSR1)
+
+/**
+ * For internal uses
+ * The address of the PHY is fixed as "0x0A".
+ */
+#define getPHYAR() \
+ WIZCHIP_READ(PHYAR)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref PHYRAR register
+ * @return uint8_t. Value of @ref PHYRAR register.
+ * @sa setPHYRAR()
+ */
+#define getPHYRAR() \
+ WIZCHIP_READ(PHYRAR)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref PHYRR register
+ * @param (uint8_t)phyrar Value to set @ref PHYRR register.
+ * @sa getPHYRR()
+ */
+#define setPHYRR(phyrar) \
+ WIZCHIP_WRITE(PHYRAR, phyrar)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref PHYDIR register
+ * @return uint16_t. Value of @ref PHYDIR register.
+ * @sa setPHYRAR()
+ */
+//read the value of the phy data input register
+#define getPHYDIR() \
+ (((uint16_t)WIZCHIP_READ(PHYDIR+1) << 8) + WIZCHIP_READ(PHYDIR))
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref PHYDIR register
+ * @param (uint16_t)phydir Value to set @ref PHYDIR register.
+ * @sa getPHYDIR()
+ */
+//write the value of the phy data input register
+#define setPHYDIR(phydir) {\
+ WIZCHIP_WRITE(PHYDIR+1, (uint8_t)(phydir >> 8)); \
+ WIZCHIP_WRITE(PHYDIR, (uint8_t) phydir); \
+ }
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref PHYDOR register
+ * @return uint16_t. Value of @ref PHYDOR register.
+ * @sa setPHYDOR()
+ */
+//read the value of the phy data output register
+#define getPHYDOR() \
+ (((uint16_t)WIZCHIP_READ(PHYDOR+1) << 8) + WIZCHIP_READ(PHYDOR))
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref PHYDOR register
+ * @param (uint16_t)phydor Value to set @ref PHYDOR register.
+ * @sa getPHYDOR()
+ */
+//write the value of the phy data output register
+#define setPHYDOR(phydor) {\
+ WIZCHIP_WRITE(PHYDOR, (uint8_t)(phydor >> 8)); \
+ WIZCHIP_WRITE(PHYDOR+1, (uint8_t) phydor); \
+ }
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref PHYACR register
+ * @return uint8_t. Value of @ref PHYACR register.
+ * @sa setPHYACR()
+ */
+//read the value of the phy action register ***This register will be cleared automatically***
+#define getPHYACR() \
+ WIZCHIP_READ(PHYACR)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref PHYACR register
+ * @param (uint8_t)phyacr Value to set @ref PHYACR register.
+ * @sa getPHYACR()
+ */
+//write the value of the phy action register
+#define setPHYACR(phyacr) \
+ WIZCHIP_WRITE(PHYACR,phyacr)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref PHYDIVR register
+ * @param (uint8_t)phydivr Value to set @ref PHYDIVR register.
+ * @sa getPHYDIVR()
+ */
+#define setPHYDIVR(phydivr) \
+ WIZCHIP_WRITE(PHYDIVR, phydivr)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref PHYDIVR register
+ * @return uint8_t. Value of @ref PHYDIVR register.
+ * @sa setPHYDIVR()
+ */
+#define getPHYDIVR() \
+ WIZCHIP_READ(PHYDIVR)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref PHYCR0 register
+ * @param (uint8_t)phych0 Value to set @ref PHYCR0 register.
+ * @sa getPHYCR0()
+ */
+#define setPHYCR0(phych0) \
+ WIZCHIP_WRITE(PHYCR0,phych0)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref PHYCR0 register
+ * @return uint8_t. Value of @ref PHYCR0 register.
+ * @sa setPHYCR0()
+ */
+#define getPHYCR0() \
+ WIZCHIP_READ(PHYCR0)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref PHYCR1 register
+ * @param (uint8_t)phycr1 Value to set @ref PHYCR1 register.
+ * @sa getPHYCR1()
+ */
+#define setPHYCR1(phycr1) \
+ WIZCHIP_WRITE(PHYCR1,phycr1)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref PHYCR1 register
+ * @return uint8_t. Value of @ref PHYCR1 register.
+ * @sa setPHYCR1()
+ */
+#define getPHYCR1() \
+ WIZCHIP_READ(PHYCR1)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref SLCR register
+ * @param (uint8_t)rqcr Value to set @ref SLCR register.
+ * @sa getSLCR()
+ */
+#define setSLCR(rqcr) \
+ WIZCHIP_WRITE(SLCR, rqcr)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref RQCR register
+ * @return uint8_t. Value of @ref RQCR register.
+ * @sa setRQCR()
+ */
+#define getSLCR() \
+ WIZCHIP_READ(RQCR)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref SLRTR register
+ * @param (uint16_t)slrtr Value to set @ref SLRTR register.
+ * @sa getSLRTR()
+ */
+#define setSLRTR(slrtr) \
+ WIZCHIP_WRITE(SLRTR, (uint8_t)(slrtr >> 8)); \
+ WIZCHIP_WRITE(SLRTR+1, (uint8_t) slrtr); \
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref SLRTR register
+ * @return uint16_t. Value of @ref SLRTR register.
+ * @sa setSLRTR()
+ */
+#define getSLRTR() \
+ (((uint16_t)WIZCHIP_READ(SLRTR) << 8) + WIZCHIP_READ(SLRTR+1))
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref SLRCR register
+ * @param (uint8_t)slrcr Value to set @ref SLRCR register.
+ * @sa getSLRCR()
+ */
+#define setSLRCR(slrcr) \
+ WIZCHIP_WRITE(SLRCR,slrcr)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref SLRCR register
+ * @return uint8_t. Value of @ref SLRCR register.
+ * @sa setSLRCR()
+ */
+#define getSLRCR() \
+ WIZCHIP_READ(SLRCR)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref SLPIPR registers
+ * @param (uint8_t*)slpipr Values to set @ref SLPIPR registers.
+ * @sa getSLPIPR()
+ */
+#define setSLPIPR(slpipr) \
+ WIZCHIP_WRITE_BUF(SLPIPR,slpipr,4)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref SLPIPR registers
+ * @param (uint8_t*)slpipr Values to get @ref SLPIPR registers.
+ * @sa getSLPIPR()
+ */
+#define getSLPIPR(slpipr) \
+ WIZCHIP_READ_BUF(SLPIPR,slpipr,4)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref SLPHAR registers
+ * @param (uint8_t*)slphar Values to set @ref SLPHAR registers.
+ * @sa getSLPHAR()
+ */
+#define setSLPHAR(slphar) \
+ WIZCHIP_WRITE_BUF(SLPHAR,slphar,6)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref SLPHAR registers
+ * @param (uint8_t*)slphar Values to get @ref SLPHAR registers.
+ * @sa getSLPHAR()
+ */
+#define getSLPHAR(slphar) \
+ WIZCHIP_READ_BUF(SLPHAR,slphar,6)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref PINGSEQR register
+ * @param (uint16_t)pingseqr Value to set @ref PINGSEQR register.
+ * @sa getPINGSEQR()
+ */
+#define setPINGSEQR(pingseqr) {\
+ WIZCHIP_WRITE(PINGSEQR, (uint8_t)(pingseqr >> 8)); \
+ WIZCHIP_WRITE(PINGSEQR+1, (uint8_t) pingseqr); \
+ }
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref PINGSEQR register
+ * @return uint16_t. Value of @ref PINGSEQR register.
+ * @sa setPINGSEQR()
+ */
+#define getPINGSEQR() \
+ (((uint16_t)WIZCHIP_READ(PINGSEQR) << 8) + WIZCHIP_READ(PINGSEQR+1))
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref PINGIDR register
+ * @param (uint16_t)pingidr Value to set @ref PINGIDR register.
+ * @sa getPINGIDR()
+ */
+#define setPINGIDR(pingidr) {\
+ WIZCHIP_WRITE(PINGIDR, (uint8_t)(pingidr >> 8)); \
+ WIZCHIP_WRITE(PINGIDR+1, (uint8_t) pingidr); \
+ }
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref PINGIDR register
+ * @return uint16_t. Value of @ref PINGIDR register.
+ * @sa setPINGIDR()
+ */
+#define getPINGIDR() \
+ (((uint16_t)WIZCHIP_READ(PINGIDR) << 8) + WIZCHIP_READ(PINGIDR+1))
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref SLIMR register
+ * @param (uint8_t)slimr Value to set @ref SLIMR register.
+ * @sa getSLIMR()
+ */
+#define setSLIMR(slimr) \
+ WIZCHIP_WRITE(SLIMR, slimr)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref SLIMR register
+ * @return uint8_t. Value of @ref SLIMR register.
+ * @sa setSLIMR()
+ */
+#define getSLIMR() \
+ WIZCHIP_READ(SLIMR)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref SLIR register
+ * @param (uint8_t)slir Value to set @ref SLIR register.
+ * @sa getSLIMR()
+ */
+#define setSLIR(slir) \
+ WIZCHIP_WRITE(SLIR, slir)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref SLIMR register
+ * @return uint8_t. Value of @ref SLIMR register.
+ * @sa setSLIMR()
+ */
+#define getSLIR() \
+ WIZCHIP_READ(SLIR)
+
+/*Hidden functions for W5100S*/
+#define setDBGOUT(dbgout) {\
+ WIZCHIP_WRITE(DBGOUT,(uint8_t)(dbgout >> 16)); \
+ WIZCHIP_WRITE(DBGOUT,(uint8_t)(dbgout >> 8)); \
+ WIZCHIP_WRITE(DBGOUT,(uint8_t)(dbgout)); \
+ }
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref NICMAXCOLR register
+ * @param (uint8_t)nicmaxcolr Value to set @ref NICMAXCOLR register.
+ * @sa getNICMAXCOLR()
+ */
+#define setNICMAXCOLR(nicmaxcolr) \
+ WIZCHIP_WRITE(NICMAXCOLR,nicmaxcolr)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref NICMAXCOLR register
+ * @return uint8_t. Value of @ref NICMAXCOLR register.
+ * @sa setNICMAXCOLR()
+ */
+#define getNICMAXCOLR() \
+ WIZCHIP_READ(NICMAXCOLR)
+
+/*Clock lock/unlock*/
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief LOCK Chip Information
+ * @sa CHIPULLOCK()
+ */
+#define CHIPLOCK() \
+ WIZCHIP_WRITE(CHIPLCKR,0xff)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Unlock Chip Information
+ * @sa CHIPLOCK()
+ */
+#define CHIPUNLOCK() \
+ WIZCHIP_WRITE(CHIPLCKR,0xCE)
+
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief LOCK Chip Information
+ * @sa CHIPULLOCK()
+ */
+/*Network information lock/unlock*/
+#define NETLOCK() \
+ WIZCHIP_WRITE(NETLCKR,0x3A)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Unlock Chip Information
+ * @sa CHIPLOCK()
+ */
+#define NETUNLOCK() \
+ WIZCHIP_WRITE(NETLCKR,0xC5)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Lock PHYCR0,CR1 Information
+ * @sa CHIPULLOCK()
+ */
+/*PHY CR0,CR1 lock/unlock*/
+#define PHYLOCK() \
+ WIZCHIP_WRITE(PHYLCKR,0xff)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Lock PHYCR0,CR1 Information
+ * @sa CHIPULLOCK()
+ */
+#define PHYUNLOCK() \
+ WIZCHIP_WRITE(PHYLCKR,0x53)
+
+/**
+ * @ingroup Version register_access_function_W5100SS
+ * @brief Get version information.
+ * @return uint16_t. It must be "0x51"
+ */
+#define getVER() \
+ (WIZCHIP_READ(VERR))
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref TCNTR register
+ * @return uint16_t. Value of @ref TCNTR register.
+ * @sa setNTCNTR()
+ */
+/*Get 100us internal counter*/
+#define getTCNTR() \
+ (((uint16_t)WIZCHIP_READ(TCNTR) << 8) + WIZCHIP_READ(TCNTR+1))
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref TCNTR register
+ * @param (uint8_t)
+ Value to set @ref TCNTR register.
+ * @sa getTCNTCLKR()
+ */
+/*Reset 100us internal counter(TCNTR)*/
+#define setTCNTCLKR(var) \
+ WIZCHIP_WRITE(TCNTCLKR, var)
+
+/*w5100s only end*/
+
+
+
+
+
+///////////////////////////////////
+// Socket N register I/O function //
+///////////////////////////////////
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Set @ref Sn_MR register
+ * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_ expect bit 4.
+ * @param mr Value to set @ref Sn_MR
+ * @sa getSn_MR()
+ */
+#define setSn_MR(sn, mr) \
+ WIZCHIP_WRITE(Sn_MR(sn),mr)
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get @ref Sn_MR register
+ * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_ expect bit 4.
+ * @return Value of @ref Sn_MR.
+ * @sa setSn_MR()
+ */
+#define getSn_MR(sn) \
+ WIZCHIP_READ(Sn_MR(sn))
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Set @ref Sn_CR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param (uint8_t)cr Value to set @ref Sn_CR
+ * @sa getSn_CR()
+ */
+#define setSn_CR(sn, cr) \
+ WIZCHIP_WRITE(Sn_CR(sn), cr)
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get @ref Sn_CR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint8_t. Value of @ref Sn_CR.
+ * @sa setSn_CR()
+ */
+#define getSn_CR(sn) \
+ WIZCHIP_READ(Sn_CR(sn))
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Set @ref Sn_IR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param (uint8_t)ir Value to set @ref Sn_IR
+ * @sa getSn_IR()
+ */
+#define setSn_IR(sn, ir) \
+ WIZCHIP_WRITE(Sn_IR(sn), ir)
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get @ref Sn_IR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint8_t. Value of @ref Sn_IR.
+ * @sa setSn_IR()
+ */
+#define getSn_IR(sn) \
+ WIZCHIP_READ(Sn_IR(sn))
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get @ref Sn_SR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint8_t. Value of @ref Sn_SR.
+ */
+#define getSn_SR(sn) \
+ WIZCHIP_READ(Sn_SR(sn))
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Set @ref Sn_PORT register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param (uint16_t)port Value to set @ref Sn_PORT.
+ * @sa getSn_PORT()
+ */
+#define setSn_PORT(sn, port) { \
+ WIZCHIP_WRITE(Sn_PORT(sn), (uint8_t)(port >> 8)); \
+ WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_PORT(sn),1), (uint8_t) port); \
+ }
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get @ref Sn_PORT register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint16_t. Value of @ref Sn_PORT.
+ * @sa setSn_PORT()
+ */
+#define getSn_PORT(sn) \
+ (((uint16_t)WIZCHIP_READ(Sn_PORT(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_PORT(sn),1)))
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Set @ref Sn_DHAR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param (uint8_t*)dhar Pointer variable to set socket n destination hardware address. It should be allocated 6 bytes.
+ * @sa getSn_DHAR()
+ */
+#define setSn_DHAR(sn, dhar) \
+ WIZCHIP_WRITE_BUF(Sn_DHAR(sn), dhar, 6)
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get @ref Sn_DHAR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param (uint8_t*)dhar Pointer variable to get socket n destination hardware address. It should be allocated 6 bytes.
+ * @sa setSn_DHAR()
+ */
+#define getSn_DHAR(sn, dhar) \
+ WIZCHIP_READ_BUF(Sn_DHAR(sn), dhar, 6)
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Set @ref Sn_DIPR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param (uint8_t*)dipr Pointer variable to set socket n destination IP address. It should be allocated 4 bytes.
+ * @sa getSn_DIPR()
+ */
+#define setSn_DIPR(sn, dipr) \
+ WIZCHIP_WRITE_BUF(Sn_DIPR(sn), dipr, 4)
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get @ref Sn_DIPR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param (uint8_t*)dipr Pointer variable to get socket n destination IP address. It should be allocated 4 bytes.
+ * @sa SetSn_DIPR()
+ */
+#define getSn_DIPR(sn, dipr) \
+ WIZCHIP_READ_BUF(Sn_DIPR(sn), dipr, 4)
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Set @ref Sn_DPORT register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param (uint16_t)dport Value to set @ref Sn_DPORT
+ * @sa getSn_DPORT()
+ */
+#define setSn_DPORT(sn, dport) { \
+ WIZCHIP_WRITE(Sn_DPORT(sn), (uint8_t) (dport>>8)); \
+ WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_DPORT(sn),1), (uint8_t) dport); \
+ }
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get @ref Sn_DPORT register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint16_t. Value of @ref Sn_DPORT.
+ * @sa setSn_DPORT()
+ */
+#define getSn_DPORT(sn) \
+ (((uint16_t)WIZCHIP_READ(Sn_DPORT(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_DPORT(sn),1)))
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Set @ref Sn_MSSR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param (uint16_t)mss Value to set @ref Sn_MSSR
+ * @sa setSn_MSSR()
+ */
+#define setSn_MSSR(sn, mss) { \
+ WIZCHIP_WRITE(Sn_MSSR(sn), (uint8_t)(mss>>8)); \
+ WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_MSSR(sn),1), (uint8_t) mss); \
+ }
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get @ref Sn_MSSR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint16_t. Value of @ref Sn_MSSR.
+ * @sa setSn_MSSR()
+ */
+#define getSn_MSSR(sn) \
+ (((uint16_t)WIZCHIP_READ(Sn_MSSR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_MSSR(sn),1)))
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Set @ref Sn_PROTO register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param (uint8_t)proto Value to set \ref Sn_PROTO
+ * @sa getSn_PROTO()
+ */
+#define setSn_PROTO(sn, proto) \
+ WIZCHIP_WRITE(Sn_PROTO(sn), proto)
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get @ref Sn_PROTO register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint8_t. Value of @ref Sn_PROTO.
+ * @sa setSn_PROTO()
+ */
+#define getSn_PROTO(sn) \
+ WIZCHIP_READ(Sn_PROTO(sn))
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Set @ref Sn_TOS register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param (uint8_t)tos Value to set @ref Sn_TOS
+ * @sa getSn_TOS()
+ */
+#define setSn_TOS(sn, tos) \
+ WIZCHIP_WRITE(Sn_TOS(sn), tos)
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get @ref Sn_TOS register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_ .
+ * @return uint8_t. Value of Sn_TOS.
+ * @sa setSn_TOS()
+ */
+#define getSn_TOS(sn) \
+ WIZCHIP_READ(Sn_TOS(sn))
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Set @ref Sn_TTL register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_ .
+ * @param (uint8_t)ttl Value to set @ref Sn_TTL
+ * @sa getSn_TTL()
+ */
+#define setSn_TTL(sn, ttl) \
+ WIZCHIP_WRITE(Sn_TTL(sn), ttl)
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get @ref Sn_TTL register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_ .
+ * @return uint8_t. Value of @ref Sn_TTL.
+ * @sa setSn_TTL()
+ */
+#define getSn_TTL(sn) \
+ WIZCHIP_READ(Sn_TTL(sn))
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Set @ref Sn_RXMEM_SIZE register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_ .
+ * @param (uint8_t)rxmemsize Value to set \ref Sn_RXMEM_SIZE
+ * @sa getSn_RXMEM_SIZE()
+ */
+#define setSn_RXMEM_SIZE(sn, rxmemsize) \
+ WIZCHIP_WRITE(RMSR, (WIZCHIP_READ(RMSR) & ~(0x03 << (2*sn))) | (rxmemsize << (2*sn)))
+#define setSn_RXBUF_SIZE(sn,rxmemsize) setSn_RXMEM_SIZE(sn,rxmemsize)
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get @ref Sn_RXMEM_SIZE register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint8_t. Value of @ref Sn_RXMEM.
+ * @sa setSn_RXMEM_SIZE()
+ */
+#define getSn_RXMEM_SIZE(sn) \
+ ((WIZCHIP_READ(RMSR) & (0x03 << (2*sn))) >> (2*sn))
+#define getSn_RXBUF_SIZE(sn) getSn_RXMEM_SIZE(sn)
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Set @ref Sn_TXMEM_SIZE register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param (uint8_t)txmemsize Value to set \ref Sn_TXMEM_SIZE
+ * @sa getSn_TXMEM_SIZE()
+ */
+#define setSn_TXMEM_SIZE(sn, txmemsize) \
+ WIZCHIP_WRITE(TMSR, (WIZCHIP_READ(TMSR) & ~(0x03 << (2*sn))) | (txmemsize << (2*sn)))
+#define setSn_TXBUF_SIZE(sn, txmemsize) setSn_TXMEM_SIZE(sn,txmemsize)
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get @ref Sn_TXMEM_SIZE register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint8_t. Value of @ref Sn_TXMEM_SIZE.
+ * @sa setSn_TXMEM_SIZE()
+ */
+#define getSn_TXMEM_SIZE(sn) \
+ ((WIZCHIP_READ(TMSR) & (0x03 << (2*sn))) >> (2*sn))
+#define getSn_TXBUF_SIZE(sn) getSn_TXMEM_SIZE(sn)
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get @ref Sn_TX_FSR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint16_t. Value of @ref Sn_TX_FSR.
+ */
+uint16_t getSn_TX_FSR(uint8_t sn);
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get @ref Sn_TX_RD register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint16_t. Value of @ref Sn_TX_RD.
+ */
+#define getSn_TX_RD(sn) \
+ (((uint16_t)WIZCHIP_READ(Sn_TX_RD(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_RD(sn),1)))
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Set @ref Sn_TX_WR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param (uint16_t)txwr Value to set @ref Sn_TX_WR
+ * @sa GetSn_TX_WR()
+ */
+#define setSn_TX_WR(sn, txwr) { \
+ WIZCHIP_WRITE(Sn_TX_WR(sn), (uint8_t)(txwr>>8)); \
+ WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_TX_WR(sn),1), (uint8_t) txwr); \
+ }
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get @ref Sn_TX_WR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint16_t. Value of @ref Sn_TX_WR.
+ * @sa setSn_TX_WR()
+ */
+#define getSn_TX_WR(sn) \
+ (((uint16_t)WIZCHIP_READ(Sn_TX_WR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_WR(sn),1)))
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get @ref Sn_RX_RSR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint16_t. Value of @ref Sn_RX_RSR.
+ */
+uint16_t getSn_RX_RSR(uint8_t sn);
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Set @ref Sn_RX_RD register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param (uint16_t)rxrd Value to set @ref Sn_RX_RD
+ * @sa getSn_RX_RD()
+ */
+#define setSn_RX_RD(sn, rxrd) { \
+ WIZCHIP_WRITE(Sn_RX_RD(sn), (uint8_t)(rxrd>>8)); \
+ WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_RX_RD(sn),1), (uint8_t) rxrd); \
+ }
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get @ref Sn_RX_RD register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @regurn uint16_t. Value of @ref Sn_RX_RD.
+ * @sa setSn_RX_RD()
+ */
+#define getSn_RX_RD(sn) \
+ (((uint16_t)WIZCHIP_READ(Sn_RX_RD(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RD(sn),1)))
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Set @ref Sn_RX_WR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param (uint16_t)rxwr Value to set \ref Sn_RX_WR
+ * @sa getSn_RX_WR()
+ */
+#define setSn_RX_WR(sn, rxwr) { \
+ WIZCHIP_WRITE(Sn_RX_WR(sn), (uint8_t)(rxwr>>8)); \
+ WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_RX_WR(sn),1), (uint8_t) rxwr); \
+ }
+
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get @ref Sn_RX_WR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint16_t. Value of @ref Sn_RX_WR.
+ */
+#define getSn_RX_WR(sn) \
+ (((uint16_t)WIZCHIP_READ(Sn_RX_WR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_WR(sn),1)))
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Set @ref Sn_FRAGR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param (uint16_t)frag Value to set \ref Sn_FRAGR
+ * @sa getSn_FRAG()
+ */
+#define setSn_FRAGR(sn, fragr) { \
+ WIZCHIP_WRITE(Sn_FRAGR(sn), (uint8_t)(fragr >>8)); \
+ WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_FRAGR(sn),1), (uint8_t) fragr); \
+ }
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get @ref Sn_FRAGR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint16_t. Value of @ref Sn_FRAGR.
+ * @sa setSn_FRAG()
+ */
+#define getSn_FRAGR(sn) \
+ (((uint16_t)WIZCHIP_READ(Sn_FRAGR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_FRAGR(sn),1)))
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get the max RX buffer size of socket sn
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint16_t. Max buffer size
+ */
+#define getSn_RxMAX(sn) \
+ ((uint16_t)(getSn_RXMEM_SIZE(sn)) << 10)
+
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get the max TX buffer size of socket sn
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint16_t. Max buffer size
+ */
+#define getSn_TxMAX(sn) \
+ ((uint16_t)(getSn_TXMEM_SIZE(sn)) << 10)
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get the mask of socket sn RX buffer.
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint16_t. Mask value
+ */
+#define getSn_RxMASK(sn) \
+ (getSn_RxMAX(sn) - 1)
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get the mask of socket sn TX buffer
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint16_t. Mask value
+ */
+#define getSn_TxMASK(sn) \
+ (getSn_TxMAX(sn) - 1)
+
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get the base address of socket sn RX buffer.
+ * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint16_t. Value of Socket n RX buffer base address.
+ */
+uint32_t getSn_RxBASE(uint8_t sn);
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get the base address of socket sn TX buffer.
+ * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint16_t. Value of Socket n TX buffer base address.
+ */
+uint32_t getSn_TxBASE(uint8_t sn);
+
+
+/*socket register W5100S only*/
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Set the interrupt mask register of socket sn.
+ * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param (uint16_t)imr Value to set \ref Sn_IMR
+ * @sa getSn_IMR(sn)
+ */
+#define setSn_IMR(sn,imr) \
+ WIZCHIP_WRITE(Sn_IMR(sn),imr)
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get the interrupt mask register of socket sn.
+ * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint16_t. Value of Socket n interrupt mask register.
+ */
+#define getSn_IMR(sn) \
+ WIZCHIP_READ(Sn_IMR(sn))
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Set the Sn_MR2 value of socket sn.
+ * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param mr2 Value of Sn_MR2 register to set.
+ */
+#define setSn_MR2(sn,mr2) \
+ WIZCHIP_WRITE(Sn_MR2(sn), mr2)
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get the Sn_MR2 value of socket sn.
+ * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint16_t. Value of Socket n Sn_MR2 register.
+ */
+#define getSn_MR2(sn) \
+ WIZCHIP_READ(Sn_MR2(sn))
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Set the Sn_KPALVTR value of socket sn.
+ * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param kpalvtr Value of the Sn_KPALVTR register to set.
+ */
+#define setSn_KPALVTR(sn,kpalvtr) \
+ WIZCHIP_WRITE(Sn_KPALVTR(sn), kpalvtr)
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get the Sn_KPALVTR value of socket sn
+ * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint8_t. Value of the Sn_KPALVTR register.
+ */
+#define getSn_KPALVTR(sn) \
+ WIZCHIP_READ(Sn_KPALVTR(sn))
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get the Sn_TSR register of socket sn.
+ * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint8_t. Value of the Socket n Sn_TSR register.
+ */
+#define getSn_TSR(sn) \
+ WIZCHIP_READ(Sn_TSR(sn))
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Set the Sn_RTR register of socket sn.
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param (uint16_t)rtr Value of the Socket n Sn_RTR register to set.
+ */
+#define setSn_RTR(sn,rtr) { \
+ WIZCHIP_WRITE(Sn_RTR(sn), (uint8_t)(rtr >> 8)); \
+ WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_RTR(sn),1), (uint8_t) rtr); \
+ }
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get the Sn_RTR register of socket sn.
+ * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint16_t. Value of the Socket n Sn_RTR register.
+ */
+#define getSn_RTR(sn) \
+ (((uint16_t)WIZCHIP_READ(Sn_RTR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RTR(sn),1)))
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Set the Sn_RCR register of socket sn.
+ * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint8_t. Value of the Socket n Sn_RCR register to set.
+ */
+#define setSn_RCR(sn,rcr) \
+ WIZCHIP_WRITE(Sn_RCR(sn),rcr)
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get the Sn_RCR of socket sn.
+ * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint8_t. Value of the Socket n Sn_RCR.
+ */
+#define getSn_RCR(sn) \
+ WIZCHIP_READ(Sn_RCR(sn))
+
+/////////////////////////////////////
+// Sn_TXBUF & Sn_RXBUF IO function //
+/////////////////////////////////////
+/**
+ * @ingroup Basic_IO_function_W5100S
+ * @brief It copies data to internal TX memory
+ *
+ * @details This function reads the Tx write pointer register and after that,
+ * it copies the wizdata(pointer buffer) of the length of len(variable) bytes to internal TX memory
+ * and updates the Tx write pointer register.
+ * This function is being called by send() and sendto() function also.
+ *
+ * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param wizdata Pointer buffer to write data
+ * @param len Data length
+ * @sa wiz_recv_data()
+ */
+void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint16_t len);
+
+/**
+ * @ingroup Basic_IO_function_W5100S
+ * @brief It copies data to your buffer from internal RX memory
+ *
+ * @details This function read the Rx read pointer register and after that,
+ * it copies the received data from internal RX memory
+ * to wizdata(pointer variable) of the length of len(variable) bytes.
+ * This function is being called by recv() also.
+ *
+ * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param wizdata Pointer buffer to read data
+ * @param len Data length
+ * @sa wiz_send_data()
+ */
+void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len);
+
+/**
+ * @ingroup Basic_IO_function_W5100S
+ * @brief It discard the received data in RX memory.
+ * @details It discards the data of the length of len(variable) bytes in internal RX memory.
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param len Data length
+ */
+void wiz_recv_ignore(uint8_t sn, uint16_t len);
+
+/**
+ * @ingroup Special_function_W5100S
+ * @brief Write data to the PHY via MDC/MDIO interface.
+ * @details Write command data to the PHY via MDC/MDIO interface.
+ * @param (uint8_t)PHYMDIO_regadr Address of the PHY register. It should be PHYMDIO_BMCR or PHYMDIO_BMSR.
+ * @param (uint16_t)var Data to write to the PHY register. Please refer to the bit definitions of the BMCR and BMSR register.
+ */
+void wiz_mdio_write(uint8_t PHYMDIO_regadr, uint16_t var);
+
+/**
+ * @ingroup Special_function_W5100S
+ * @brief Read data from the PHY via MDC/MDIO interface.
+ * @details Read command or status data from the PHY via MDC/MDIO interface.
+ * @param (uint8_t)PHYMDIO_regadr Address of the PHY register. It should be PHYMDIO_BMCR or PHYMDIO_BMSR.
+ * @return The value of the PHY register
+ */
+uint16_t wiz_mdio_read(uint8_t PHYMDIO_regadr);
+
+/**
+ * @ingroup Special_function_W5100S
+ * @brief Delay function
+ * @details Delay function using internal 100us timer of the W5100S
+ * @param (uint32_t)ms Time to delay in milliseconds.
+ */
+void wiz_delay_ms(uint32_t ms);
+
+/// @cond DOXY_APPLY_CODE
+#endif
+/// @endcond
+
+#endif //_W5100S_H_
+
+
+
diff --git a/Libraries/ioLibrary_Driver/Ethernet/W5200/w5200.c b/Libraries/ioLibrary_Driver/Ethernet/W5200/w5200.c
new file mode 100644
index 0000000..fbfcc1b
--- /dev/null
+++ b/Libraries/ioLibrary_Driver/Ethernet/W5200/w5200.c
@@ -0,0 +1,404 @@
+//*****************************************************************************
+//
+//! \file w5200.c
+//! \brief W5200 HAL Interface.
+//! \version 1.0.0
+//! \date 2013/10/21
+//! \par Revision history
+//! <2013/10/21> 1st Release
+//! \author MidnightCow
+//!
+//! Copyright (c) 2013, WIZnet Co., LTD.
+//! All rights reserved.
+//!
+//! Redistribution and use in source and binary forms, with or without
+//! modification, are permitted provided that the following conditions
+//! are met:
+//!
+//! * Redistributions of source code must retain the above copyright
+//! notice, this list of conditions and the following disclaimer.
+//! * Redistributions in binary form must reproduce the above copyright
+//! notice, this list of conditions and the following disclaimer in the
+//! documentation and/or other materials provided with the distribution.
+//! * Neither the name of the nor the names of its
+//! contributors may be used to endorse or promote products derived
+//! from this software without specific prior written permission.
+//!
+//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+//! THE POSSIBILITY OF SUCH DAMAGE.
+//
+//*****************************************************************************
+
+#include "w5200.h"
+
+#if (_WIZCHIP_ == 5200)
+/**
+@brief This function writes the data into W5200 registers.
+*/
+void WIZCHIP_WRITE(uint32_t AddrSel, uint8_t wb )
+{
+#if defined(SPI_DMA)
+ uint8_t pTmpBuf[5];
+#endif
+ WIZCHIP_CRITICAL_ENTER();
+ WIZCHIP.CS._select();
+
+#if( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_))
+ #if !defined (SPI_DMA)
+ WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8);
+ WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0);
+ WIZCHIP.IF.SPI._write_byte(_W5200_SPI_WRITE_); // Data write command and Write data length upper
+ WIZCHIP.IF.SPI._write_byte(0x01); // Write data length lower
+ WIZCHIP.IF.SPI._write_byte(wb); // Data write (write 1byte data)
+ #else
+ pTmpBuf[0] = (AddrSel & 0xFF00)>>8;
+ pTmpBuf[1] = (AddrSel & 0x00FF);
+ pTmpBuf[2] = (_W5200_SPI_WRITE_ & 0x80);
+ pTmpBuf[3] = (0x01 & 0xFF);
+
+ pTmpBuf[4] = wb;
+
+ WIZCHIP.IF.SPI._write_burst(pTmpBuf,5);
+ #endif
+#elif ( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_) )
+
+ //add indirect bus
+ //M20150601 : Rename the function for integrating with W5300
+ //WIZCHIP.IF.BUS._write_byte(IDM_AR0,(AddrSel & 0x0000FF00) >> 8);
+ //WIZCHIP.IF.BUS._write_byte(IDM_AR1,(AddrSel & 0x000000FF));
+ //WIZCHIP.IF.BUS._write_byte(IDM_DR,wb);
+ WIZCHIP.IF.BUS._write_data(IDM_AR0,(AddrSel & 0x0000FF00) >> 8);
+ WIZCHIP.IF.BUS._write_data(IDM_AR1,(AddrSel & 0x000000FF));
+ WIZCHIP.IF.BUS._write_data(IDM_DR,wb);
+
+#else
+ #error "Unknown _WIZCHIP_IO_MODE_ in W5200. !!!"
+#endif
+
+ WIZCHIP.CS._deselect();
+ WIZCHIP_CRITICAL_EXIT();
+}
+/**
+@brief This function reads the value from W5200 registers.
+*/
+uint8_t WIZCHIP_READ(uint32_t AddrSel)
+{
+ #if defined(SPI_DMA)
+ uint8_t pTmpBuf[5];
+ #endif
+ uint8_t ret;
+
+ WIZCHIP_CRITICAL_ENTER();
+ WIZCHIP.CS._select();
+
+#if( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_))
+ #if !defined (SPI_DMA)
+ WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8);
+ WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0);
+ WIZCHIP.IF.SPI._write_byte(_W5200_SPI_READ_); // Read data length upper
+ WIZCHIP.IF.SPI._write_byte(0x01); // Data length lower
+ ret = WIZCHIP.IF.SPI._read_byte();
+ #else
+ pTmpBuf[0] = (AddrSel & 0xFF00)>> 8;
+ pTmpBuf[1] = (AddrSel & 0x00FF);
+ pTmpBuf[2] = (_W5200_SPI_READ_ & 0x80);
+ pTmpBuf[3] = (0x01 & 0xFF);
+
+ WIZCHIP.IF.SPI._read_burst(pTmpBuf, 5);
+
+ ret = pTmpBuf[4];
+ #endif
+
+#elif ( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_) )
+
+ //add indirect bus
+ //M20150601 : Rename the function for integrating with W5300
+ //WIZCHIP.IF.BUS._write_byte(IDM_AR0,(AddrSel & 0x0000FF00) >> 8);
+ //WIZCHIP.IF.BUS._write_byte(IDM_AR1,(AddrSel & 0x000000FF));
+ //ret = WIZCHIP.IF.BUS._read_byte(IDM_DR);
+ WIZCHIP.IF.BUS._write_data(IDM_AR0,(AddrSel & 0x0000FF00) >> 8);
+ WIZCHIP.IF.BUS._write_data(IDM_AR1,(AddrSel & 0x000000FF));
+ ret = WIZCHIP.IF.BUS._read_data(IDM_DR);
+
+#else
+ #error "Unknown _WIZCHIP_IO_MODE_ in W5200. !!!"
+#endif
+
+ WIZCHIP.CS._deselect();
+ WIZCHIP_CRITICAL_EXIT();
+ return ret;
+}
+
+
+/**
+@brief This function writes into W5200 memory(Buffer)
+*/
+void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len)
+{
+#if defined(SPI_DMA)
+ uint8_t pTmpBuf[5];
+#endif
+ uint16_t i = 0;
+ WIZCHIP_CRITICAL_ENTER();
+ WIZCHIP.CS._select();
+
+#if( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_))
+ #if !defined(SPI_DMA)
+ WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8);
+ WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0);
+ WIZCHIP.IF.SPI._write_byte(_W5200_SPI_WRITE_ | ((len & 0x7F00) >> 8)); // Write data op code and length upper
+ WIZCHIP.IF.SPI._write_byte((len & 0x00FF) >> 0); // length lower
+ for(i = 0; i < len; i++)
+ WIZCHIP.IF.SPI._write_byte(pBuf[i]);
+ #else
+ pTmpBuf[0] = (AddrSel & 0xFF00)>>8;
+ pTmpBuf[1] = (AddrSel & 0x00FF);
+ pTmpBuf[2] = ((_W5200_SPI_WRITE_) |((len & 0x7F00)>>8));
+ pTmpBuf[3] = (len & 0x00FF);
+ WIZCHIP.IF.SPI._write_burst(pTmpBuf,4);
+ WIZCHIP.IF.SPI._write_burst(pBuf,len);
+ #endif
+
+#elif ( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_) )
+ //M20150601 : Rename the function for integrating with W5300
+ /*
+ WIZCHIP_WRITE(MR,WIZCHIP_READ(MR) | MR_AI);
+ WIZCHIP.IF.BUS._write_byte(IDM_AR0,(AddrSel & 0x0000FF00) >> 8);
+ WIZCHIP.IF.BUS._write_byte(IDM_AR1,(AddrSel & 0x000000FF));
+ for(i = 0 ; i < len; i++)
+ WIZCHIP.IF.BUS._write_byte(IDM_DR,pBuf[i]);
+ WIZCHIP_WRITE(MR, WIZCHIP_READ(MR) & ~MR_AI);
+ */
+ setMR(getMR() | MR_AI);
+ WIZCHIP.IF.BUS._write_data(IDM_AR0,(AddrSel & 0x0000FF00) >> 8);
+ WIZCHIP.IF.BUS._write_data(IDM_AR1,(AddrSel & 0x000000FF));
+ for(i = 0 ; i < len; i++)
+ WIZCHIP.IF.BUS._write_data(IDM_DR,pBuf[i]);
+ WIZCHIP_WRITE(MR, WIZCHIP_READ(MR) & ~MR_AI);
+#else
+ #error "Unknown _WIZCHIP_IO_MODE_ in W5200. !!!!"
+#endif
+
+ WIZCHIP.CS._deselect();
+ WIZCHIP_CRITICAL_EXIT();
+}
+
+/**
+@brief This function reads into W5200 memory(Buffer)
+*/
+void WIZCHIP_READ_BUF (uint32_t AddrSel, uint8_t* pBuf, uint16_t len)
+{
+ #if defined(SPI_DMA)
+ uint8_t pTmpBuf[4];
+ #endif
+ uint16_t i = 0;
+ WIZCHIP_CRITICAL_ENTER();
+ WIZCHIP.CS._select();
+
+#if( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_))
+ #if !defined(SPI_DMA)
+ WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8);
+ WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0);
+ WIZCHIP.IF.SPI._write_byte( _W5200_SPI_READ_ | ((len & 0x7F00) >> 8)); // Write data op code and length upper
+ WIZCHIP.IF.SPI._write_byte((len & 0x00FF) >> 0); // length lower
+ for(i = 0; i < len; i++)
+ pBuf[i] = WIZCHIP.IF.SPI._read_byte();
+ #else
+ pTmpBuf[0] = (AddrSel & 0xFF00)>>8;
+ pTmpBuf[1] = (AddrSel & 0x00FF);
+ pTmpBuf[2] = ((_W5200_SPI_READ_)| (len & 0x7F00)>>8);
+ pTmpBuf[3] = (len & 0x00FF);
+ WIZCHIP.IF.SPI._write_burst(pTmpBuf,4);
+ WIZCHIP.IF.SPI._read_burst(pBuf,len);
+ #endif
+
+#elif ( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_) )
+ //M20150601 : Rename the function for integrating with W5300
+ /*
+ WIZCHIP_WRITE(MR, WIZCHIP_READ(MR) | MR_AI);
+ WIZCHIP.IF.BUS._write_byte(IDM_AR0,(AddrSel & 0x0000FF00) >> 8);
+ WIZCHIP.IF.BUS._write_byte(IDM_AR1,(AddrSel & 0x000000FF));
+ for(i = 0 ; i < len; i++)
+ pBuf[i] = WIZCHIP.IF.BUS._read_byte(IDM_DR);
+ WIZCHIP_WRITE(MR, WIZCHIP_READ(MR) & ~MR_AI);
+ */
+ setMR(getMR() | MR_AI);
+ WIZCHIP.IF.BUS._write_data(IDM_AR0,(AddrSel & 0x0000FF00) >> 8);
+ WIZCHIP.IF.BUS._write_data(IDM_AR1,(AddrSel & 0x000000FF));
+ for(i = 0 ; i < len; i++)
+ pBuf[i] = WIZCHIP.IF.BUS._read_data(IDM_DR);
+ setMR(getMR() & ~MR_AI);
+#else
+ #error "Unknown _WIZCHIP_IO_MODE_ in W5200. !!!!"
+#endif
+
+ WIZCHIP.CS._deselect();
+ WIZCHIP_CRITICAL_EXIT();
+}
+
+///////////////////////////////////
+// Socket N regsiter IO function //
+///////////////////////////////////
+
+uint16_t getSn_TX_FSR(uint8_t sn)
+{
+ uint16_t val=0,val1=0;
+ do
+ {
+ val1 = WIZCHIP_READ(Sn_TX_FSR(sn));
+ val1 = (val1 << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn),1));
+ if (val1 != 0)
+ {
+ val = WIZCHIP_READ(Sn_TX_FSR(sn));
+ val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn),1));
+ }
+ }while (val != val1);
+ return val;
+}
+
+
+uint16_t getSn_RX_RSR(uint8_t sn)
+{
+ uint16_t val=0,val1=0;
+ do
+ {
+ val1 = WIZCHIP_READ(Sn_RX_RSR(sn));
+ val1 = (val1 << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn),1));
+ if (val1 != 0)
+ {
+ val = WIZCHIP_READ(Sn_RX_RSR(sn));
+ val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn),1));
+ }
+ }while (val != val1);
+ return val;
+}
+
+/////////////////////////////////////
+// Sn_TXBUF & Sn_RXBUF IO function //
+/////////////////////////////////////
+
+uint16_t getSn_RxBASE(uint8_t sn)
+{
+ int8_t i;
+ uint16_t rxbase = _WIZCHIP_IO_RXBUF_;
+ for(i = 0; i < sn; i++)
+ rxbase += getSn_RxMAX(i);
+ return rxbase;
+}
+
+uint16_t getSn_TxBASE(uint8_t sn)
+{
+ int8_t i;
+ uint16_t txbase = _WIZCHIP_IO_TXBUF_;
+ for(i = 0; i < sn; i++)
+ txbase += getSn_TxMAX(i);
+ return txbase;
+}
+
+/**
+@brief This function is being called by send() and sendto() function also. for copy the data form application buffer to Transmite buffer of the chip.
+
+This function read the Tx write pointer register and after copy the data in buffer update the Tx write pointer
+register. User should read upper byte first and lower byte later to get proper value.
+And this function is being used for copy the data form application buffer to Transmite
+buffer of the chip. It calculate the actual physical address where one has to write
+the data in transmite buffer. Here also take care of the condition while it exceed
+the Tx memory uper-bound of socket.
+
+*/
+
+void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint16_t len)
+{
+
+ uint16_t ptr;
+ uint16_t size;
+ uint16_t dst_mask;
+ uint8_t * dst_ptr;
+
+ ptr = getSn_TX_WR(sn);
+
+
+ dst_mask = (uint32_t)ptr & getSn_TxMASK(sn);
+ dst_ptr = (uint8_t*)((uint32_t)getSn_TxBASE(sn) + dst_mask);
+
+ if (dst_mask + len > getSn_TxMAX(sn))
+ {
+ size = getSn_TxMAX(sn) - dst_mask;
+ WIZCHIP_WRITE_BUF((uint32_t)dst_ptr, wizdata, size);
+ wizdata += size;
+ size = len - size;
+ dst_ptr = (uint8_t*)((uint32_t)getSn_TxBASE(sn));
+ WIZCHIP_WRITE_BUF((uint32_t)dst_ptr, wizdata, size);
+ }
+ else
+ {
+ WIZCHIP_WRITE_BUF((uint32_t)dst_ptr, wizdata, len);
+ }
+
+ ptr += len;
+
+ setSn_TX_WR(sn, ptr);
+}
+
+
+/**
+@brief This function is being called by recv() also. This function is being used for copy the data form Receive buffer of the chip to application buffer.
+
+This function read the Rx read pointer register
+and after copy the data from receive buffer update the Rx write pointer register.
+User should read upper byte first and lower byte later to get proper value.
+It calculate the actual physical address where one has to read
+the data from Receive buffer. Here also take care of the condition while it exceed
+the Rx memory uper-bound of socket.
+*/
+void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len)
+{
+ uint16_t ptr;
+ uint16_t size;
+ uint16_t src_mask;
+ uint8_t * src_ptr;
+
+ ptr = getSn_RX_RD(sn);
+
+ src_mask = (uint32_t)ptr & getSn_RxMASK(sn);
+ src_ptr = (uint8_t *)((uint32_t)getSn_RxBASE(sn) + src_mask);
+
+ if( (src_mask + len) > getSn_RxMAX(sn) )
+ {
+ size = getSn_RxMAX(sn) - src_mask;
+ WIZCHIP_READ_BUF((uint32_t)src_ptr, (uint8_t*)wizdata, size);
+ wizdata += size;
+ size = len - size;
+ src_ptr = (uint8_t*)((uint32_t)getSn_RxBASE(sn));
+ WIZCHIP_READ_BUF((uint32_t)src_ptr, (uint8_t*)wizdata, size);
+ }
+ else
+ {
+ WIZCHIP_READ_BUF((uint32_t)src_ptr, (uint8_t*)wizdata, len);
+ }
+
+ ptr += len;
+
+ setSn_RX_RD(sn, ptr);
+}
+
+void wiz_recv_ignore(uint8_t sn, uint16_t len)
+{
+ uint16_t ptr;
+
+ ptr = getSn_RX_RD(sn);
+
+ ptr += len;
+ setSn_RX_RD(sn,ptr);
+}
+
+#endif
diff --git a/Libraries/ioLibrary_Driver/Ethernet/W5200/w5200.h b/Libraries/ioLibrary_Driver/Ethernet/W5200/w5200.h
new file mode 100644
index 0000000..7df5ff4
--- /dev/null
+++ b/Libraries/ioLibrary_Driver/Ethernet/W5200/w5200.h
@@ -0,0 +1,2101 @@
+//* ****************************************************************************
+//! \file w5200.h
+//! \brief W5200 HAL Header File.
+//! \version 1.0.0
+//! \date 2015/03/23
+//! \par Revision history
+//! <2013/10/21> 1st Release
+//! \author MidnightCow
+//! \copyright
+//!
+//! Copyright (c) 2013, WIZnet Co., LTD.
+//! All rights reserved.
+//!
+//! Redistribution and use in source and binary forms, with or without
+//! modification, are permitted provided that the following conditions
+//! are met:
+//!
+//! * Redistributions of source code must retain the above copyright
+//! notice, this list of conditions and the following disclaimer.
+//! * Redistributions in binary form must reproduce the above copyright
+//! notice, this list of conditions and the following disclaimer in the
+//! documentation and/or other materials provided with the distribution.
+//! * Neither the name of the nor the names of its
+//! contributors may be used to endorse or promote products derived
+//! from this software without specific prior written permission.
+//!
+//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+//! THE POSSIBILITY OF SUCH DAMAGE.
+//
+//*****************************************************************************
+
+#ifndef _W5200_H
+#define _W5200_H
+#include
+#include "wizchip_conf.h"
+
+/// \cond DOXY_APPLY_CODE
+#if (_WIZCHIP_ == 5200)
+/// \endcond
+
+#define _WIZCHIP_SN_BASE_ (0x4000)
+#define _WIZCHIP_SN_SIZE_ (0x0100)
+#define _WIZCHIP_IO_TXBUF_ (0x8000) /* Internal Tx buffer address of the iinchip */
+#define _WIZCHIP_IO_RXBUF_ (0xC000) /* Internal Rx buffer address of the iinchip */
+
+#define _W5200_SPI_READ_ (0x00 << 7) ///< SPI interface Read operation in Control Phase
+#define _W5200_SPI_WRITE_ (0x01 << 7) ///< SPI interface Write operation in Control Phase
+
+#define WIZCHIP_CREG_BLOCK 0x00 ///< Common register block
+#define WIZCHIP_SREG_BLOCK(N) (_WIZCHIP_SN_BASE_+ _WIZCHIP_SN_SIZE_*N) ///< Socket N register block
+
+#define WIZCHIP_OFFSET_INC(ADDR, N) (ADDR + N) ///< Increase offset address
+
+#if (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_)
+ #define IDM_AR0 ((_WIZCHIP_IO_BASE_ + 0x0001))
+ #define IDM_AR1 ((_WIZCHIP_IO_BASE_ + 0x0002))
+ #define IDM_DR ((_WIZCHIP_IO_BASE_ + 0x0003))
+ #define _W5200_IO_BASE_ 0x0000
+#elif (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_)
+ #define _W5200_IO_BASE_ 0x0000
+#endif
+
+///////////////////////////////////////
+// Definition For Legacy Chip Driver //
+///////////////////////////////////////
+#define IINCHIP_READ(ADDR) WIZCHIP_READ(ADDR) ///< The defined for legacy chip driver
+#define IINCHIP_WRITE(ADDR,VAL) WIZCHIP_WRITE(ADDR,VAL) ///< The defined for legacy chip driver
+#define IINCHIP_READ_BUF(ADDR,BUF,LEN) WIZCHIP_READ_BUF(ADDR,BUF,LEN) ///< The defined for legacy chip driver
+#define IINCHIP_WRITE_BUF(ADDR,BUF,LEN) WIZCHIP_WRITE(ADDR,BUF,LEN) ///< The defined for legacy chip driver
+
+
+//----------- defgroup --------------------------------
+
+/**
+ * @defgroup W5200 W5200
+ * @brief WHIZCHIP register defines and I/O functions of @b W5200.
+ *
+ * - @ref WIZCHIP_register_W5200 : @ref Common_register_group_W5200 and @ref Socket_register_group_W5200
+ * - @ref WIZCHIP_IO_Functions_W5200 : @ref Basic_IO_function_W5200, @ref Common_register_access_function_W5200 and @ref Socket_register_group_W5200
+ */
+
+ /**
+ * @defgroup WIZCHIP_register_W5200 WIZCHIP register
+ * @ingroup W5200
+ * @brief WIZCHIP register defines register group of W5200 .
+ *
+ * - \ref Common_register_group_W5200 : Common register group w5200
+ * - \ref Socket_register_group_W5200 : \c SOCKET n register group w5200
+ */
+
+
+/**
+ * @defgroup WIZCHIP_IO_Functions_W5200 WIZCHIP I/O functions
+ * @ingroup W5200
+ * @brief This supports the basic I/O functions for \ref WIZCHIP_register_W5200.
+ *
+ * - Basic I/O function \n
+ * WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF() \n\n
+ *
+ * - \ref Common_register_group_W5200 access functions \n
+ * -# @b Mode \n
+ * getMR(), setMR()
+ * -# @b Interrupt \n
+ * getIR(), setIR(), getIMR(), setIMR(), getIR2(), setIR2(), getIMR2(), setIMR2(), getINTLEVEL(), setINTLEVEL()
+ * -# Network Information \n
+ * getSHAR(), setSHAR(), getGAR(), setGAR(), getSUBR(), setSUBR(), getSIPR(), setSIPR()
+ * -# @b Retransmission \n
+ * getRCR(), setRCR(), getRTR(), setRTR()
+ * -# @b PPPoE \n
+ * getPTIMER(), setPTIMER(), getPMAGIC(), getPMAGIC()
+ * -# @b etc. \n
+ * getPHYSTATUS(), getVERSIONR() \n\n
+ *
+ * - \ref Socket_register_group_W5200 access functions \n
+ * -# SOCKET control \n
+ * getSn_MR(), setSn_MR(), getSn_CR(), setSn_CR(), getSn_IMR(), setSn_IMR(), getSn_IR(), setSn_IR()
+ * -# SOCKET information \n
+ * getSn_SR(), getSn_DHAR(), setSn_DHAR(), getSn_PORT(), setSn_PORT(), getSn_DIPR(), setSn_DIPR(), getSn_DPORT(), setSn_DPORT()
+ * getSn_MSSR(), setSn_MSSR()
+ * -# SOCKET communication \n
+ * getSn_RXMEM_SIZE(), setSn_RXMEM_SIZE(), getSn_TXMEM_SIZE(), setSn_TXMEM_SIZE() \n
+ * getSn_TX_RD(), getSn_TX_WR(), setSn_TX_WR() \n
+ * getSn_RX_RD(), setSn_RX_RD(), getSn_RX_WR() \n
+ * getSn_TX_FSR(), getSn_RX_RSR()
+ * -# IP header field \n
+ * getSn_FRAG(), setSn_FRAG(), getSn_TOS(), setSn_TOS() \n
+ * getSn_TTL(), setSn_TTL()
+ */
+
+/**
+ * @defgroup Common_register_group_W5200 Common register
+ * @ingroup WIZCHIP_register_W5200
+ * @brief Common register group\n
+ * It set the basic for the networking\n
+ * It set the configuration such as interrupt, network information, ICMP, etc.
+ * @details
+ * @sa MR : Mode register.
+ * @sa GAR, SUBR, SHAR, SIPR
+ * @sa INTLEVEL, IR, _IMR_, IR2, IMR2 : Interrupt.
+ * @sa _RTR_, _RCR_ : Data retransmission.
+ * @sa PTIMER, PMAGIC : PPPoE.
+ * @sa PHYSTATUS, VERSIONR : etc.
+ */
+
+
+ /**
+ * @defgroup Socket_register_group_W5200 Socket register
+ * @ingroup WIZCHIP_register_W5200
+ * @brief Socket register group\n
+ * Socket register configures and control SOCKETn which is necessary to data communication.
+ * @details
+ * @sa Sn_MR, Sn_CR, Sn_IR, Sn_IMR : SOCKETn Control
+ * @sa Sn_SR, Sn_PORT, Sn_DHAR, Sn_DIPR, Sn_DPORT : SOCKETn Information
+ * @sa Sn_MSSR, Sn_TOS, Sn_TTL, Sn_FRAG : Internet protocol.
+ * @sa Sn_RXMEM_SIZE, Sn_TXMEM_SIZE, Sn_TX_FSR, Sn_TX_RD, Sn_TX_WR, Sn_RX_RSR, Sn_RX_RD, Sn_RX_WR : Data communication
+ */
+
+ /**
+ * @defgroup Basic_IO_function_W5200 Basic I/O function
+ * @ingroup WIZCHIP_IO_Functions_W5200
+ * @brief These are basic input/output functions to read values from register or write values to register.
+ */
+
+/**
+ * @defgroup Common_register_access_function_W5200 Common register access functions
+ * @ingroup WIZCHIP_IO_Functions_W5200
+ * @brief These are functions to access common registers.
+ */
+
+/**
+ * @defgroup Socket_register_access_function_W5200 Socket register access functions
+ * @ingroup WIZCHIP_IO_Functions_W5200
+ * @brief These are functions to access socket registers.
+ */
+
+ //-----------------------------------------------------------------------------------
+
+//----------------------------- W5200 Common Registers IOMAP -----------------------------
+/**
+ * @ingroup Common_register_group_W5200
+ * @brief Mode Register address(R/W)\n
+ * \ref MR is used for S/W reset, ping block mode, PPPoE mode and etc.
+ * @details Each bit of \ref MR defined as follows.
+ *
+ *
7
6
5
4
3
2
1
0
+ *
RST
Reserved
WOL
PB
PPPoE
Reserved
AI
IND
+ *
+ * - \ref MR_RST : Reset
+ * - \ref MR_WOL : Wake on LAN
+ * - \ref MR_PB : Ping block
+ * - \ref MR_PPPOE : PPPoE mode
+ * - \ref MR_AI : Address Auto-Increment in Indirect Bus Interface
+ * - \ref MR_IND : Indirect Bus Interface mode
+ */
+#if (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_)
+ #define MR (_WIZCHIP_IO_BASE_ + (0x0000)) // Mode
+#else
+ #define MR (_W5200_IO_BASE_ + (0x0000)) // Mode
+#endif
+
+/**
+ * @ingroup Common_register_group_W5200
+ * @brief Gateway IP Register address(R/W)
+ * @details \ref GAR configures the default gateway address.
+ */
+#define GAR (_W5200_IO_BASE_ + (0x0001)) // GW Address
+
+/**
+ * @ingroup Common_register_group_W5200
+ * @brief Subnet mask Register address(R/W)
+ * @details \ref SUBR configures the subnet mask address.
+ */
+#define SUBR (_W5200_IO_BASE_ + (0x0005)) // SN Mask Address
+
+/**
+ * @ingroup Common_register_group_W5200
+ * @brief Source MAC Register address(R/W)
+ * @details \ref SHAR configures the source hardware address.
+ */
+#define SHAR (_W5200_IO_BASE_ + (0x0009)) // Source Hardware Address
+
+/**
+ * @ingroup Common_register_group_W5200
+ * @brief Source IP Register address(R/W)
+ * @details \ref SIPR configures the source IP address.
+ */
+#define SIPR (_W5200_IO_BASE_ + (0x000F)) // Source IP Address
+
+// Reserved (_W5200_IO_BASE_ + (0x0013))
+// Reserved (_W5200_IO_BASE_ + (0x0014))
+
+/**
+ * @ingroup Common_register_group_W5200
+ * @brief Interrupt Register(R/W)
+ * @details \ref IR indicates the interrupt status. Each bit of \ref IR will be still until the bit will be written to by the host.
+ * If \ref IR is not equal to x00 INTn PIN is asserted to low until it is x00\n\n
+ * Each bit of \ref IR defined as follows.
+ *
+ *
7
6
5
4
3
2
1
0
+ *
CONFLICT
Reserved
PPPoE
Reserved
Reserved
Reserved
Reserved
Reserved
+ *
+ * - \ref IR_CONFLICT : IP conflict
+ * - \ref IR_PPPoE : PPPoE connection close
+ */
+#define IR (_W5200_IO_BASE_ + (0x0015)) // Interrupt
+
+/**
+ * @ingroup Common_register_group_W5200
+ * @brief Socket Interrupt Mask Register(R/W)
+ * @details Each bit of \ref _IMR_ corresponds to each bit of \ref IR2.
+ * When a bit of \ref _IMR_ is and the corresponding bit of \ref IR2 is Interrupt will be issued.
+ * In other words, if a bit of \ref _IMR_, an interrupt will be not issued even if the corresponding bit of \ref IR2 is set
+ * @note This Register is same operated as SMIR of W5100, W5300 and W5550.\n
+ * So, \ref setSIMR() set a value to _IMR_ for integrating with ioLibrary
+ */
+#define _IMR_ (_W5200_IO_BASE_ + (0x0016)) // Socket Interrupt Mask
+
+/**
+ * @ingroup Common_register_group_W5200
+ * @brief Timeout register address( 1 is 100us )(R/W)
+ * @details \ref _RTR_ configures the retransmission timeout period. The unit of timeout period is 100us and the default of \ref _RTR_ is x07D0.
+ * And so the default timeout period is 200ms(100us X 2000). During the time configured by \ref _RTR_, W5200 waits for the peer response
+ * to the packet that is transmitted by \ref Sn_CR (CONNECT, DISCON, CLOSE, SEND, SEND_MAC, SEND_KEEP command).
+ * If the peer does not respond within the \ref _RTR_ time, W5200 retransmits the packet or issues timeout.
+ */
+#define _RTR_ (_W5200_IO_BASE_ + (0x0017)) // Retry Time
+
+/**
+ * @ingroup Common_register_group_W5200
+ * @brief Retry count register(R/W)
+ * @details \ref _RCR_ configures the number of time of retransmission.
+ * When retransmission occurs as many as ref _RCR_+1 Timeout interrupt is issued (\ref Sn_IR_TIMEOUT = '1').
+ */
+#define _RCR_ (_W5200_IO_BASE_ + (0x0019)) // Retry Count
+
+// Reserved (_W5200_IO_BASE_ + (0x001A))
+// Reserved (_W5200_IO_BASE_ + (0x001B))
+
+/**
+ * @ingroup Common_register_group_W5200
+ * @brief PPP LCP Request Timer register in PPPoE mode(R)
+ * @details \ref PATR notifies authentication method that has been agreed at the connection with
+ * PPPoE Server. W5200 supports two types of Authentication method - PAP and CHAP.
+ */
+#define PATR (_W5200_IO_BASE_ + (0x001C))
+
+/**
+ * @ingroup Common_register_group_W5200
+ * @brief PPP LCP Request Timer register in PPPoE mode(R)
+ * @details \ref PPPALGO notifies authentication algorithm in PPPoE mode. For detailed information,
+ * please refer to PPPoE application note.
+ */
+#define PPPALGO (_W5200_IO_BASE_ + (0x001E)) // Authentication Algorithm in PPPoE
+
+/**
+ * @ingroup Common_register_group_W5200
+ * @brief chip version register address(R)
+ * @details \ref VERSIONR always indicates the W5200 version as @b 0x03.
+ */
+#define VERSIONR (_W5200_IO_BASE_ + (0x001F)) // Chip version
+
+// Reserved (_W5200_IO_BASE_ + (0x0020))
+// Reserved (_W5200_IO_BASE_ + (0x0021))
+// Reserved (_W5200_IO_BASE_ + (0x0022))
+// Reserved (_W5200_IO_BASE_ + (0x0023))
+// Reserved (_W5200_IO_BASE_ + (0x0024))
+// Reserved (_W5200_IO_BASE_ + (0x0025))
+// Reserved (_W5200_IO_BASE_ + (0x0026))
+// Reserved (_W5200_IO_BASE_ + (0x0027))
+
+/**
+ * @ingroup Common_register_group_W5200
+ * @brief PPP LCP Request Timer register in PPPoE mode(R)
+ * @details \ref PTIMER configures the time for sending LCP echo request. The unit of time is 25ms.
+ */
+#define PTIMER (_W5200_IO_BASE_ + (0x0028)) // PPP LCP RequestTimer
+
+/**
+ * @ingroup Common_register_group_W5200
+ * @brief PPP LCP Magic number register in PPPoE mode(R)
+ * @details \ref PMAGIC configures the 4bytes magic number to be used in LCP negotiation.
+ */
+#define PMAGIC (_W5200_IO_BASE_ + (0x0029)) // PPP LCP Magic number
+
+// Reserved (_W5200_IO_BASE_ + (0x002A))
+// Reserved (_W5200_IO_BASE_ + (0x002B))
+// Reserved (_W5200_IO_BASE_ + (0x002C))
+// Reserved (_W5200_IO_BASE_ + (0x002D))
+// Reserved (_W5200_IO_BASE_ + (0x002E))
+// Reserved (_W5200_IO_BASE_ + (0x002F))
+
+/**
+ * @ingroup Common_register_group_W5200
+ * @brief Set Interrupt low level timer register address(R/W)
+ * @details \ref INTLEVEL configures the Interrupt Assert Time.
+ */
+#define INTLEVEL (_W5200_IO_BASE_ + (0x0030)) // Interrupt Low Level Timer
+
+// Reserved (_W5200_IO_BASE_ + (0x0032))
+// Reserved (_W5200_IO_BASE_ + (0x0033))
+
+/**
+ * @ingroup Common_register_group_W5200
+ * @brief Socket Interrupt Register(R/W)
+ * @details \ref IR2 indicates the interrupt status of Socket.\n
+ * Each bit of \ref IR2 be still until \ref Sn_IR is cleared by the host.\n
+ * If \ref Sn_IR is not equal to x00 the n-th bit of \ref IR2 is and INTn PIN is asserted until \ref IR2 is x00 */
+#define IR2 (_W5200_IO_BASE_ + (0x0034)) // Socket Interrupt
+
+/**
+ * @ingroup Common_register_group_W5200
+ * @brief PHYSTATUS(R/W)
+ * @details \ref PHYSTATUS is the Register to indicate W5200 status of PHY.
+ *
+ *
7
6
5
4
3
2
1
0
+ *
Reserved
Reserved
LINK
POWERSAVE
POWERDOWN
Reserved
Reserved
Reserved
+ *
+ * - \ref PHYSTATUS_LINK : Link Status Register[Read Only]
+ * - \ref PHYSTATUS_POWERSAVE : Power save mode of PHY[R/W]
+ * - \ref PHYSTATUS_POWERDOWN : Power down mode of PHY[R/W]
+ */
+#define PHYSTATUS (_W5200_IO_BASE_ + (0x0035)) // PHY Status
+
+/**
+ * @ingroup Common_register_group_W5200
+ * @brief Interrupt mask register(R/W)
+ * @details \ref IMR2 is used to mask interrupts. Each bit of \ref _IMR_ corresponds to each bit of \ref IR.
+ * When a bit of \ref IMR2 is and the corresponding bit of \ref IR is an interrupt will be issued. In other words,
+ * if a bit of \ref IMR2 is an interrupt will not be issued even if the corresponding bit of \ref IR is \n\n
+ * Each bit of \ref IMR2 defined as the following.
+ *
+ *
7
6
5
4
3
2
1
0
+ *
IM_IR7
Reserved
IM_IR5
Reserved
Reserved
Reserved
Reserved
Reserved
+ *
+ * - \ref IM_IR7 : IP Conflict Interrupt Mask
+ * - \ref IM_IR5 : PPPoE Close Interrupt Mask
+ * @note This Register is same operated as _IMR_ of W5100, W5300 and W5550.\n
+ * So, \ref setIMR() set a value to IMR2 for integrating with ioLibrary
+ */
+#define IMR2 (_W5200_IO_BASE_ + (0x0036)) // Interrupt Mask
+
+
+//----------------------------- W5200 Socket Registers -----------------------------
+
+//--------------------------- For Backward Compatibility ---------------------------
+
+/**
+ * @ingroup Socket_register_group_W5200
+ * @brief socket Mode register(R/W)
+ * @details \ref Sn_MR configures the option or protocol type of Socket n.\n\n
+ * Each bit of \ref Sn_MR defined as the following.
+ *
+ *
7
6
5
4
3
2
1
0
+ *
MULTI
MF
ND/MC
Reserved
Protocol[3]
Protocol[2]
Protocol[1]
Protocol[0]
+ *
+ * - \ref Sn_MR_MULTI : Support UDP Multicasting
+ * - \ref Sn_MR_MF : Support MACRAW
+ * - \ref Sn_MR_ND : No Delayed Ack(TCP) flag
+ * - \ref Sn_MR_MC : IGMP version used in UDP mulitcasting
+ * - Protocol
+ *
+ *
Protocol[3]
Protocol[2]
Protocol[1]
Protocol[0]
@b Meaning
+ *
0
0
0
0
Closed
+ *
0
0
0
1
TCP
+ *
0
0
1
0
UDP
+ *
0
1
0
0
MACRAW
+ *
+ * - In case of Socket 0
+ *
+ *
Protocol[3]
Protocol[2]
Protocol[1]
Protocol[0]
@b Meaning
+ *
0
1
0
0
MACRAW
+ *
0
1
0
1
PPPoE
+ *
+ * - \ref Sn_MR_MACRAW : MAC LAYER RAW SOCK \n
+ * - \ref Sn_MR_UDP : UDP
+ * - \ref Sn_MR_TCP : TCP
+ * - \ref Sn_MR_CLOSE : Unused socket
+ * @note MACRAW mode should be only used in Socket 0.
+ */
+#define Sn_MR(sn) (_W5200_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0000)) // socket Mode register
+
+/**
+ * @ingroup Socket_register_group_W5200
+ * @brief Socket command register(R/W)
+ * @details This is used to set the command for Socket n such as OPEN, CLOSE, CONNECT, LISTEN, SEND, and RECEIVE.\n
+ * After W5200 accepts the command, the \ref Sn_CR register is automatically cleared to 0x00.
+ * Even though \ref Sn_CR is cleared to 0x00, the command is still being processed.\n
+ * To check whether the command is completed or not, please check the \ref Sn_IR or \ref Sn_SR.
+ * - \ref Sn_CR_OPEN : Initialize or open socket.
+ * - \ref Sn_CR_LISTEN : Wait connection request in TCP mode(Server mode)
+ * - \ref Sn_CR_CONNECT : Send connection request in TCP mode(Client mode)
+ * - \ref Sn_CR_DISCON : Send closing request in TCP mode.
+ * - \ref Sn_CR_CLOSE : Close socket.
+ * - \ref Sn_CR_SEND : Update TX buffer pointer and send data.
+ * - \ref Sn_CR_SEND_MAC : Send data with MAC address, so without ARP process.
+ * - \ref Sn_CR_SEND_KEEP : Send keep alive message.
+ * - \ref Sn_CR_RECV : Update RX buffer pointer and receive data.
+ * - In case of S0_MR(P3:P0) = S0_MR_PPPoE
+ *
+ *
Value
Symbol
Description
+ *
0x23
PCON
PPPoE connection begins by transmitting PPPoE discovery packet
+ *
0x24
PDISCON
Closes PPPoE connection
+ *
0x25
PCR
In each phase, it transmits REQ message.
+ *
0x26
PCN
In each phase, it transmits NAK message.
+ *
0x27
PCJ
In each phase, it transmits REJECT message.
+ *
+ */
+#define Sn_CR(sn) (_W5200_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0001)) // channel Sn_CR register
+
+/**
+ * @ingroup Socket_register_group_W5200
+ * @brief Socket interrupt register(R)
+ * @details \ref Sn_IR indicates the status of Socket Interrupt such as establishment, termination, receiving data, timeout).\n
+ * When an interrupt occurs and the corresponding bit of \ref Sn_IMR is the corresponding bit of \ref Sn_IR becomes \n
+ * In order to clear the \ref Sn_IR bit, the host should write the bit to \n
+ *
+ *
7
6
5
4
3
2
1
0
+ *
PRECV
PFAIL
PNEXT
SEND_OK
TIMEOUT
RECV
DISCON
CON
+ *
+ * - \ref Sn_IR_PRECV : PPP Receive Interrupt
+ * - \ref Sn_IR_PFAIL : PPP Fail Interrupt
+ * - \ref Sn_IR_PNEXT : PPP Next Phase Interrupt
+ * - \ref Sn_IR_SENDOK : SEND_OK Interrupt
+ * - \ref Sn_IR_TIMEOUT : TIMEOUT Interrupt
+ * - \ref Sn_IR_RECV : RECV Interrupt
+ * - \ref Sn_IR_DISCON : DISCON Interrupt
+ * - \ref Sn_IR_CON : CON Interrupt
+ */
+#define Sn_IR(sn) (_W5200_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0002)) // channel interrupt register
+
+/**
+ * @ingroup Socket_register_group_W5200
+ * @brief Socket status register(R)
+ * @details \ref Sn_SR indicates the status of Socket n.\n
+ * The status of Socket n is changed by \ref Sn_CR or some special control packet as SYN, FIN packet in TCP.
+ * @par Normal status
+ * - \ref SOCK_CLOSED : Closed
+ * - \ref SOCK_INIT : Initiate state
+ * - \ref SOCK_LISTEN : Listen state
+ * - \ref SOCK_ESTABLISHED : Success to connect
+ * - \ref SOCK_CLOSE_WAIT : Closing state
+ * - \ref SOCK_UDP : UDP socket
+ * - \ref SOCK_MACRAW : MAC raw mode socket
+ *@par Temporary status during changing the status of Socket n.
+ * - \ref SOCK_SYNSENT : This indicates Socket n sent the connect-request packet (SYN packet) to a peer.
+ * - \ref SOCK_SYNRECV : It indicates Socket n successfully received the connect-request packet (SYN packet) from a peer.
+ * - \ref SOCK_FIN_WAIT : Connection state
+ * - \ref SOCK_CLOSING : Closing state
+ * - \ref SOCK_TIME_WAIT : Closing state
+ * - \ref SOCK_LAST_ACK : Closing state
+ */
+#define Sn_SR(sn) (_W5200_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0003)) // channel status register
+
+/**
+ * @ingroup Socket_register_group_W5200
+ * @brief source port register(R/W)
+ * @details \ref Sn_PORT configures the source port number of Socket n.
+ * It is valid when Socket n is used in TCP/UDP mode. It should be set before OPEN command is ordered.
+*/
+#define Sn_PORT(sn) (_W5200_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0004)) // source port register
+
+/**
+ * @ingroup Socket_register_group_W5200
+ * @brief Peer MAC register address(R/W)
+ * @details \ref Sn_DHAR configures the destination hardware address of Socket n when using SEND_MAC command in UDP mode or
+ * it indicates that it is acquired in ARP-process by CONNECT/SEND command.
+ */
+#define Sn_DHAR(sn) (_W5200_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0006)) // Peer MAC register address
+
+/**
+ * @ingroup Socket_register_group_W5200
+ * @brief Peer IP register address(R/W)
+ * @details \ref Sn_DIPR configures or indicates the destination IP address of Socket n. It is valid when Socket n is used in TCP/UDP mode.
+ * In TCP client mode, it configures an IP address of TCP server before CONNECT command.
+ * In TCP server mode, it indicates an IP address of TCP client after successfully establishing connection.
+ * In UDP mode, it configures an IP address of peer to be received the UDP packet by SEND or SEND_MAC command.
+ */
+#define Sn_DIPR(sn) (_W5200_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x000C)) // Peer IP register address
+
+/**
+ * @ingroup Socket_register_group_W5200
+ * @brief Peer port register address(R/W)
+ * @details \ref Sn_DPORT configures or indicates the destination port number of Socket n. It is valid when Socket n is used in TCP/UDP mode.
+ * In TCP clientmode, it configures the listen port number of TCP server before CONNECT command.
+ * In TCP Servermode, it indicates the port number of TCP client after successfully establishing connection.
+ * In UDP mode, it configures the port number of peer to be transmitted the UDP packet by SEND/SEND_MAC command.
+ */
+#define Sn_DPORT(sn) (_W5200_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0010)) // Peer port register address
+
+/**
+ * @ingroup Socket_register_group_W5200
+ * @brief Maximum Segment Size(Sn_MSSR0) register address(R/W)
+ * @details \ref Sn_MSSR configures or indicates the MTU(Maximum Transfer Unit) of Socket n.
+ */
+#define Sn_MSSR(sn) (_W5200_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0012)) // Maximum Segment Size(Sn_MSSR0) register address
+
+/**
+ * @ingroup Socket_register_group_W5200
+ * @brief IP Protocol(PROTO) Register(R/W)
+ * @details \ref Sn_PROTO that sets the protocol number field of the IP header at the IP layer. It is
+ * valid only in IPRAW mode, and ignored in other modes.
+ */
+#define Sn_PROTO(sn) (_W5200_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0014)) // Protocol of IP Header field register in IP raw mode
+
+/**
+ * @ingroup Socket_register_group_W5200
+ * @brief IP Type of Service(TOS) Register(R/W)
+ * @details \ref Sn_TOS configures the TOS(Type Of Service field in IP Header) of Socket n.
+ * It is set before OPEN command.
+ */
+#define Sn_TOS(sn) (WIZCHIP_SREG_BLOCK(sn) + 0x0015) // IP Type of Service(TOS) Register
+
+/**
+ * @ingroup Socket_register_group_W5200
+ * @brief IP Time to live(TTL) Register(R/W)
+ * @details \ref Sn_TTL configures the TTL(Time To Live field in IP header) of Socket n.
+ * It is set before OPEN command.
+ */
+#define Sn_TTL(sn) (_W5200_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0016)) // IP Time to live(TTL) Register
+
+// Reserved (_W5200_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0017))
+// Reserved (_W5200_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0018))
+// Reserved (_W5200_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0019))
+// Reserved (_W5200_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x001A))
+// Reserved (_W5200_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x001B))
+// Reserved (_W5200_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x001C))
+// Reserved (_W5200_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x001D))
+
+/**
+ * @ingroup Socket_register_group_W5200
+ * @brief Receive memory size register(R/W)
+ * @details \ref Sn_RXMEM_SIZE configures the RX buffer block size of Socket n.
+ * Socket n RX Buffer Block size can be configured with 1,2,4,8, and 16 Kbytes.
+ * If a different size is configured, the data cannot be normally received from a peer.
+ * Although Socket n RX Buffer Block size is initially configured to 2Kbytes,
+ * user can re-configure its size using \ref Sn_RXMEM_SIZE. The total sum of \ref Sn_RXMEM_SIZE can not be exceed 16Kbytes.
+ * When exceeded, the data reception error is occurred.
+ */
+#define Sn_RXMEM_SIZE(sn) (_W5200_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x001E)) // Receive memory size reigster
+
+/**
+ * @ingroup Socket_register_group_W5200
+ * @brief Transmit memory size register(R/W)
+ * @details \ref Sn_TXMEM_SIZE configures the TX buffer block size of Socket n. Socket n TX Buffer Block size can be configured with 1,2,4,8, and 16 Kbytes.
+ * If a different size is configured, the data can't be normally transmitted to a peer.
+ * Although Socket n TX Buffer Block size is initially configured to 2Kbytes,
+ * user can be re-configure its size using \ref Sn_TXMEM_SIZE. The total sum of \ref Sn_TXMEM_SIZE can not be exceed 16Kbytes.
+ * When exceeded, the data transmission error is occurred.
+ */
+#define Sn_TXMEM_SIZE(sn) (_W5200_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x001F)) // Transmit memory size reigster
+
+/**
+ * @ingroup Socket_register_group_W5200
+ * @brief Transmit free memory size register(R)
+ * @details \ref Sn_TX_FSR indicates the free size of Socket n TX Buffer Block. It is initialized to the configured size by \ref Sn_TXMEM_SIZE.
+ * Data bigger than \ref Sn_TX_FSR should not be saved in the Socket n TX Buffer because the bigger data overwrites the previous saved data not yet sent.
+ * Therefore, check before saving the data to the Socket n TX Buffer, and if data is equal or smaller than its checked size,
+ * transmit the data with SEND/SEND_MAC command after saving the data in Socket n TX buffer. But, if data is bigger than its checked size,
+ * transmit the data after dividing into the checked size and saving in the Socket n TX buffer.
+ */
+#define Sn_TX_FSR(sn) (_W5200_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0020)) // Transmit free memory size register
+
+/**
+ * @ingroup Socket_register_group_W5200
+ * @brief Transmit memory read pointer register address(R)
+ * @details \ref Sn_TX_RD is initialized by OPEN command. However, if Sn_MR(P[3:0]) is TCP mode(001), it is re-initialized while connecting with TCP.
+ * After its initialization, it is auto-increased by SEND command.
+ * SEND command transmits the saved data from the current \ref Sn_TX_RD to the \ref Sn_TX_WR in the Socket n TX Buffer.
+ * After transmitting the saved data, the SEND command increases the \ref Sn_TX_RD as same as the \ref Sn_TX_WR.
+ * If its increment value exceeds the maximum value 0xFFFF, (greater than 0x10000 and the carry bit occurs),
+ * then the carry bit is ignored and will automatically update with the lower 16bits value.
+ */
+#define Sn_TX_RD(sn) (_W5200_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0022)) // Transmit memory read pointer register address
+
+/**
+ * @ingroup Socket_register_group_W5200
+ * @brief Transmit memory write pointer register address(R/W)
+ * @details \ref Sn_TX_WR is initialized by OPEN command. However, if Sn_MR(P[3:0]) is TCP mode(001), it is re-initialized while connecting with TCP.\n
+ * It should be read or be updated like as follows.\n
+ * 1. Read the starting address for saving the transmitting data.\n
+ * 2. Save the transmitting data from the starting address of Socket n TX buffer.\n
+ * 3. After saving the transmitting data, update \ref Sn_TX_WR to the increased value as many as transmitting data size.
+ * If the increment value exceeds the maximum value 0xFFFF(greater than 0x10000 and the carry bit occurs),
+ * then the carry bit is ignored and will automatically update with the lower 16bits value.\n
+ * 4. Transmit the saved data in Socket n TX Buffer by using SEND/SEND command
+ */
+#define Sn_TX_WR(sn) (_W5200_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0024)) // Transmit memory write pointer register address
+
+/**
+ * @ingroup Socket_register_group_W5200
+ * @brief Received data size register(R)
+ * @details \ref Sn_RX_RSR indicates the data size received and saved in Socket n RX Buffer.
+ * \ref Sn_RX_RSR does not exceed the \ref Sn_RXMEM_SIZE and is calculated as the difference between
+ * Socket n RX Write Pointer (\ref Sn_RX_WR)and Socket n RX Read Pointer (\ref Sn_RX_RD)
+ */
+#define Sn_RX_RSR(sn) (_W5200_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0026)) // Received data size register
+
+/**
+ * @ingroup Socket_register_group_W5200
+ * @brief Read point of Receive memory(R/W)
+ * @details \ref Sn_RX_RD is initialized by OPEN command. Make sure to be read or updated as follows.\n
+ * 1. Read the starting save address of the received data.\n
+ * 2. Read data from the starting address of Socket n RX Buffer.\n
+ * 3. After reading the received data, Update \ref Sn_RX_RD to the increased value as many as the reading size.
+ * If the increment value exceeds the maximum value 0xFFFF, that is, is greater than 0x10000 and the carry bit occurs,
+ * update with the lower 16bits value ignored the carry bit.\n
+ * 4. Order RECV command is for notifying the updated \ref Sn_RX_RD to W5200.
+ */
+#define Sn_RX_RD(sn) (_W5200_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0028)) // Read point of Receive memory
+
+/**
+ * @ingroup Socket_register_group_W5200
+ * @brief Write point of Receive memory(R)
+ * @details \ref Sn_RX_WR is initialized by OPEN command and it is auto-increased by the data reception.
+ * If the increased value exceeds the maximum value 0xFFFF, (greater than 0x10000 and the carry bit occurs),
+ * then the carry bit is ignored and will automatically update with the lower 16bits value.
+ */
+#define Sn_RX_WR(sn) (_W5200_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x002A)) // Write point of Receive memory
+
+/**
+ * @ingroup Socket_register_group_W5200
+ * @brief socket interrupt mask register(R)
+ * @details \ref Sn_IMR masks the interrupt of Socket n.
+ * Each bit corresponds to each bit of \ref Sn_IR. When a Socket n Interrupt is occurred and the corresponding bit of \ref Sn_IMR is
+ * the corresponding bit of \ref Sn_IR becomes When both the corresponding bit of \ref Sn_IMR and \ref Sn_IR are and the n-th bit of \ref IR is
+ * Host is interrupted by asserted INTn PIN to low.
+ */
+#define Sn_IMR(sn) (_W5200_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x002C)) // socket interrupt mask register
+
+/**
+ * @ingroup Socket_register_group_W5200
+ * @brief Fragment field value in IP header register(R/W)
+ * @details \ref Sn_FRAG configures the FRAG(Fragment field in IP header).
+ */
+#define Sn_FRAG(sn) (_W5200_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x002D)) // frag field value in IP header register
+
+
+//----------------------------- W5200 Register values -----------------------------
+
+/* MODE register values */
+/**
+ * @brief Reset
+ * @details If this bit is All internal registers will be initialized. It will be automatically cleared as after S/W reset.
+ */
+#define MR_RST 0x80 ///< reset
+
+/**
+ * @brief Wake on LAN
+ * @details 0 : Disable WOL mode\n
+ * 1 : Enable WOL mode\n
+ * If WOL mode is enabled and the received magic packet over UDP has been normally processed, the Interrupt PIN (INTn) asserts to low.
+ * When using WOL mode, the UDP Socket should be opened with any source port number. (Refer to Socket n Mode Register (\ref Sn_MR) for opening Socket.)
+ * @note The magic packet over UDP supported by W5200 consists of 6 bytes synchronization stream (xFFFFFFFFFFFF and
+ * 16 times Target MAC address stream in UDP payload. The options such like password are ignored. You can use any UDP source port number for WOL mode.
+ */
+#define MR_WOL 0x20 ///< Wake on Lan
+
+/**
+ * @brief Ping block
+ * @details 0 : Disable Ping block\n
+ * 1 : Enable Ping block\n
+ * If the bit is it blocks the response to a ping request.
+ */
+#define MR_PB 0x10 ///< ping block
+
+/**
+ * @brief Enable PPPoE
+ * @details 0 : DisablePPPoE mode\n
+ * 1 : EnablePPPoE mode\n
+ * If you use ADSL, this bit should be '1'.
+ */
+#define MR_PPPOE 0x08 ///< enable pppoe
+
+/**
+ * @brief Address Auto-Increment in Indirect Bus Interface
+ * @details 0 : Disable auto-increment \n
+ * 1 : Enable auto-incremente \n
+ * At the Indirect Bus Interface mode, if this bit is set as ��1��, the address will
+ * be automatically increased by 1 whenever read and write are performed.
+ */
+#define MR_AI 0x02 ///< auto-increment in indirect mode
+
+/**
+ * @brief Indirect Bus Interface mode
+ * @details 0 : Disable Indirect bus Interface mode \n
+ * 1 : Enable Indirect bus Interface mode \n
+ * If this bit is set as ��1��, Indirect Bus Interface mode is set.
+ */
+#define MR_IND 0x01 ///< enable indirect mode
+
+/* IR register values */
+/**
+ * @brief Check IP conflict.
+ * @details Bit is set as when own source IP address is same with the sender IP address in the received ARP request.
+ */
+#define IR_CONFLICT 0x80 ///< check ip confict
+
+/**
+ * @brief Get the PPPoE close message.
+ * @details When PPPoE is disconnected during PPPoE mode, this bit is set.
+ */
+#define IR_PPPoE 0x20 ///< get the PPPoE close message
+
+/**
+ * @brief Link Status [Read Only]
+ * @details 0: Link down \n 1: Link up \n
+ */
+#define PHYSTATUS_LINK 0x20
+
+/**
+ * @brief Power save mode of PHY
+ * @details 0: Disable Power save mode \n 1: Enable Power save mode \n
+ */
+#define PHYSTATUS_POWERSAVE 0x10
+
+/**
+ * @brief Power down mode of PHY
+ * @details 0: Disable Power down mode \n 1: Enable Power down mode\n
+ */
+#define PHYSTATUS_POWERDOWN 0x08
+
+// Sn_MR values
+/* Sn_MR Default values */
+/**
+ * @brief Unused socket
+ * @details This configures the protocol mode of Socket n.
+ */
+#define Sn_MR_CLOSE 0x00 ///< unused socket
+
+/**
+ * @brief TCP
+ * @details This configures the protocol mode of Socket n.
+ */
+#define Sn_MR_TCP 0x01 ///< TCP
+
+/**
+ * @brief UDP
+ * @details This configures the protocol mode of Socket n.
+ */
+#define Sn_MR_UDP 0x02 ///< UDP
+#define Sn_MR_IPRAW 0x03 ///< IP LAYER RAW SOCK
+
+/**
+ * @brief MAC LAYER RAW SOCK
+ * @details This configures the protocol mode of Socket n.
+ * @note MACRAW mode should be only used in Socket 0.
+ */
+#define Sn_MR_MACRAW 0x04 ///< MAC LAYER RAW SOCK
+
+/**
+ * @brief PPPoE
+ * @details This configures the protocol mode of Socket n.
+ * @note PPPoE mode should be only used in Socket 0.
+ */
+#define Sn_MR_PPPOE 0x05 ///< PPPoE
+
+/**
+ * @brief No Delayed Ack(TCP), Multicast flag
+ * @details 0 : Disable No Delayed ACK option\n
+ * 1 : Enable No Delayed ACK option\n
+ * This bit is applied only during TCP mode (P[3:0] = 001).\n
+ * When this bit is It sends the ACK packet without delay as soon as a Data packet is received from a peer.\n
+ * When this bit is It sends the ACK packet after waiting for the timeout time configured by \ref _RTR_.
+ */
+#define Sn_MR_ND 0x20 ///< No Delayed Ack(TCP) flag
+
+/* Sn_MR Default values */
+/**
+ * @brief Support UDP Multicasting
+ * @details 0 : disable Multicasting\n
+ * 1 : enable Multicasting\n
+ * This bit is applied only during UDP mode(P[3:0] = 010).\n
+ * To use multicasting, \ref Sn_DIPR & \ref Sn_DPORT should be respectively configured with the multicast group IP address & port number
+ * before Socket n is opened by OPEN command of \ref Sn_CR.
+ */
+#define Sn_MR_MC Sn_MR_ND ///< Select IGMP version 1(0) or 2(1)
+
+/**
+ * @brief Multicast Blocking in \ref Sn_MR_MACRAW mode
+ * @details 0 : using IGMP version 2\n
+ * 1 : using IGMP version 1\n
+ * This bit is applied only during UDP mode(P[3:0] = 010 and MULTI = '1')
+ * It configures the version for IGMP messages (Join/Leave/Report).
+ */
+#define Sn_MR_MF 0x40 ///< Use MAC filter
+#define Sn_MR_MFEN Sn_MR_MF
+
+/* Sn_MR Default values */
+/**
+ * @brief Support UDP Multicasting
+ * @details 0 : disable Multicasting\n
+ * 1 : enable Multicasting\n
+ * This bit is applied only during UDP mode(P[3:0] = 010).\n
+ * To use multicasting, \ref Sn_DIPR & \ref Sn_DPORT should be respectively configured with the multicast group IP address & port number
+ * before Socket n is opened by OPEN command of \ref Sn_CR.
+ */
+#define Sn_MR_MULTI 0x80 ///< support multicating
+
+/* Sn_CR values */
+/**
+ * @brief Initialize or open socket
+ * @details Socket n is initialized and opened according to the protocol selected in Sn_MR(P3:P0).
+ * The table below shows the value of \ref Sn_SR corresponding to \ref Sn_MR.\n
+ *
+ *
\b Sn_MR (P[3:0])
\b Sn_SR
+ *
Sn_MR_CLOSE (000)
--
+ *
Sn_MR_TCP (001)
SOCK_INIT (0x13)
+ *
Sn_MR_UDP (010)
SOCK_UDP (0x22)
+ *
S0_MR_IPRAW (011)
SOCK_IPRAW (0x32)
+ *
S0_MR_MACRAW (100)
SOCK_MACRAW (0x42)
+ *
S0_MR_PPPoE (101)
SOCK_PPPoE (0x5F)
+ *
+ */
+#define Sn_CR_OPEN 0x01 ///< initialize or open socket
+
+/**
+ * @brief Wait connection request in TCP mode(Server mode)
+ * @details This is valid only in TCP mode (Sn_MR(P3:P0) = \ref Sn_MR_TCP).//
+ * In this mode, Socket n operates as a 'TCP server' and waits for connection-request (SYN packet) from any 'TCP client'.//
+ * The \ref Sn_SR changes the state from SOCK_INIT to SOCKET_LISTEN.//
+ * When a 'TCP client' connection request is successfully established,
+ * the \ref Sn_SR changes from SOCK_LISTEN to SOCK_ESTABLISHED and the Sn_IR(0) becomes
+ * But when a 'TCP client' connection request is failed, Sn_IR(3) becomes and the status of \ref Sn_SR changes to SOCK_CLOSED.
+ */
+#define Sn_CR_LISTEN 0x02 ///< wait connection request in tcp mode(Server mode)
+
+/**
+ * @brief Send connection request in TCP mode(Client mode)
+ * @details To connect, a connect-request (SYN packet) is sent to TCP serverconfigured by \ref Sn_DIPR & Sn_DPORT(destination address & port).
+ * If the connect-request is successful, the \ref Sn_SR is changed to \ref SOCK_ESTABLISHED and the Sn_IR(0) becomes \n\n
+ * The connect-request fails in the following three cases.\n
+ * 1. When a @b ARPTO occurs (\ref Sn_IR[3] = '1') because destination hardware address is not acquired through the ARP-process.\n
+ * 2. When a @b SYN/ACK packet is not received and @b TCPTO (Sn_IR(3) ='1')\n
+ * 3. When a @b RST packet is received instead of a @b SYN/ACK packet. In these cases, \ref Sn_SR is changed to \ref SOCK_CLOSED.
+ * @note This is valid only in TCP mode and operates when Socket n acts as TCP client
+ */
+#define Sn_CR_CONNECT 0x04 ///< send connection request in tcp mode(Client mode)
+
+/**
+ * @brief Send closing request in TCP mode
+ * @details Regardless of TCP serveror TCP client the DISCON command processes the disconnect-process (Active closeor Passive close.\n
+ * @par Active close
+ * it transmits disconnect-request(FIN packet) to the connected peer\n
+ * @par Passive close
+ * When FIN packet is received from peer, a FIN packet is replied back to the peer.\n
+ * @details When the disconnect-process is successful (that is, FIN/ACK packet is received successfully), \ref Sn_SR is changed to \ref SOCK_CLOSED.\n
+ * Otherwise, TCPTO occurs (Sn_IR(3)='1') and then \ref Sn_SR is changed to \ref SOCK_CLOSED.
+ * @note Valid only in TCP mode.
+ */
+#define Sn_CR_DISCON 0x08 ///< send closing reqeuset in tcp mode
+
+/**
+ * @brief Close socket
+ * @details Sn_SR is changed to \ref SOCK_CLOSED.
+ */
+#define Sn_CR_CLOSE 0x10
+
+/**
+ * @brief Update TX buffer pointer and send data
+ * @details SEND transmits all the data in the Socket n TX buffer.\n
+ * For more details, please refer to Socket n TX Free Size Register (\ref Sn_TX_FSR), Socket n,
+ * TX Write Pointer Register(\ref Sn_TX_WR), and Socket n TX Read Pointer Register(\ref Sn_TX_RD).
+ */
+#define Sn_CR_SEND 0x20
+
+/**
+ * @brief Send data with MAC address, so without ARP process
+ * @details The basic operation is same as SEND.\n
+ * Normally SEND transmits data after destination hardware address is acquired by the automatic ARP-process(Address Resolution Protocol).\n
+ * But SEND_MAC transmits data without the automatic ARP-process.\n
+ * In this case, the destination hardware address is acquired from \ref Sn_DHAR configured by host, instead of APR-process.
+ * @note Valid only in UDP mode.
+ */
+#define Sn_CR_SEND_MAC 0x21
+
+/**
+ * @brief Send keep alive message
+ * @details It checks the connection status by sending 1byte keep-alive packet.\n
+ * If the peer can not respond to the keep-alive packet during timeout time, the connection is terminated and the timeout interrupt will occur.
+ * @note Valid only in TCP mode.
+ */
+#define Sn_CR_SEND_KEEP 0x22
+
+/**
+ * @brief Update RX buffer pointer and receive data
+ * @details RECV completes the processing of the received data in Socket n RX Buffer by using a RX read pointer register (\ref Sn_RX_RD).\n
+ * For more details, refer to Socket n RX Received Size Register (\ref Sn_RX_RSR), Socket n RX Write Pointer Register (\ref Sn_RX_WR),
+ * and Socket n RX Read Pointer Register (\ref Sn_RX_RD).
+ */
+#define Sn_CR_RECV 0x40
+
+/**
+ * @brief PPPoE connection
+ * @details PPPoE connection begins by transmitting PPPoE discovery packet
+ */
+#define Sn_CR_PCON 0x23
+
+/**
+ * @brief Closes PPPoE connection
+ * @details Closes PPPoE connection
+ */
+#define Sn_CR_PDISCON 0x24
+
+/**
+ * @brief REQ message transmission
+ * @details In each phase, it transmits REQ message.
+ */
+#define Sn_CR_PCR 0x25
+
+/**
+ * @brief NAK massage transmission
+ * @details In each phase, it transmits NAK message.
+ */
+#define Sn_CR_PCN 0x26
+
+/**
+ * @brief REJECT message transmission
+ * @details In each phase, it transmits REJECT message.
+ */
+#define Sn_CR_PCJ 0x27
+
+/* Sn_IR values */
+/**
+ * @brief PPP Receive Interrupt
+ * @details PPP Receive Interrupts when the option which is not supported is received.
+ */
+#define Sn_IR_PRECV 0x80
+
+/**
+ * @brief PPP Fail Interrupt
+ * @details PPP Fail Interrupts when PAP Authentication is failed.
+ */
+#define Sn_IR_PFAIL 0x40
+
+/**
+ * @brief PPP Next Phase Interrupt
+ * @details PPP Next Phase Interrupts when the phase is changed during ADSL connection process.
+ */
+#define Sn_IR_PNEXT 0x20
+
+/**
+ * @brief SEND_OK Interrupt
+ * @details This is issued when SEND command is completed.
+ */
+#define Sn_IR_SENDOK 0x10 ///< complete sending
+
+/**
+ * @brief TIMEOUT Interrupt
+ * @details This is issued when ARPTO or TCPTO occurs.
+ */
+#define Sn_IR_TIMEOUT 0x08 ///< assert timeout
+
+/**
+ * @brief RECV Interrupt
+ * @details This is issued whenever data is received from a peer.
+ */
+#define Sn_IR_RECV 0x04
+
+/**
+ * @brief DISCON Interrupt
+ * @details This is issued when FIN or FIN/ACK packet is received from a peer.
+ */
+#define Sn_IR_DISCON 0x02
+
+/**
+ * @brief CON Interrupt
+ * @details This is issued one time when the connection with peer is successful and then \ref Sn_SR is changed to \ref SOCK_ESTABLISHED.
+ */
+#define Sn_IR_CON 0x01
+
+/* Sn_SR values */
+/**
+ * @brief Closed
+ * @details This indicates that Socket n is released.\n
+ * When DICON, CLOSE command is ordered, or when a timeout occurs, it is changed to \ref SOCK_CLOSED regardless of previous status.
+ */
+#define SOCK_CLOSED 0x00 ///< closed
+
+/**
+ * @brief Initiate state
+ * @details This indicates Socket n is opened with TCP mode.\n
+ * It is changed to \ref SOCK_INIT when Sn_MR(P[3:0]) = 001)and OPEN command is ordered.\n
+ * After \ref SOCK_INIT, user can use LISTEN /CONNECT command.
+ */
+#define SOCK_INIT 0x13 ///< init state
+
+/**
+ * @brief Listen state
+ * @details This indicates Socket n is operating as TCP servermode and waiting for connection-request (SYN packet) from a peer (TCP client).\n
+ * It will change to \ref SOCK_ESTABLISHED when the connection-request is successfully accepted.\n
+ * Otherwise it will change to \ref SOCK_CLOSED after TCPTO occurred (Sn_IR(TIMEOUT) = '1').
+ */
+#define SOCK_LISTEN 0x14
+
+/**
+ * @brief Connection state
+ * @details This indicates Socket n sent the connect-request packet (SYN packet) to a peer.\n
+ * It is temporarily shown when \ref Sn_SR is changed from \ref SOCK_INIT to \ref SOCK_ESTABLISHED by CONNECT command.\n
+ * If connect-accept(SYN/ACK packet) is received from the peer at SOCK_SYNSENT, it changes to \ref SOCK_ESTABLISHED.\n
+ * Otherwise, it changes to \ref SOCK_CLOSED after TCPTO (\ref Sn_IR[TIMEOUT] = '1') is occurred.
+ */
+#define SOCK_SYNSENT 0x15
+
+/**
+ * @brief Connection state
+ * @details It indicates Socket n successfully received the connect-request packet (SYN packet) from a peer.\n
+ * If socket n sends the response (SYN/ACK packet) to the peer successfully, it changes to \ref SOCK_ESTABLISHED. \n
+ * If not, it changes to \ref SOCK_CLOSED after timeout occurs (\ref Sn_IR[TIMEOUT] = '1').
+ */
+#define SOCK_SYNRECV 0x16
+
+/**
+ * @brief Success to connect
+ * @details This indicates the status of the connection of Socket n.\n
+ * It changes to \ref SOCK_ESTABLISHED when the TCP SERVERprocessed the SYN packet from the TCP CLIENTduring \ref SOCK_LISTEN, or
+ * when the CONNECT command is successful.\n
+ * During \ref SOCK_ESTABLISHED, DATA packet can be transferred using SEND or RECV command.
+ */
+#define SOCK_ESTABLISHED 0x17
+
+/**
+ * @brief Closing state
+ * @details These indicate Socket n is closing.\n
+ * These are shown in disconnect-process such as active-close and passive-close.\n
+ * When Disconnect-process is successfully completed, or when timeout occurs, these change to \ref SOCK_CLOSED.
+ */
+#define SOCK_FIN_WAIT 0x18
+
+/**
+ * @brief Closing state
+ * @details These indicate Socket n is closing.\n
+ * These are shown in disconnect-process such as active-close and passive-close.\n
+ * When Disconnect-process is successfully completed, or when timeout occurs, these change to \ref SOCK_CLOSED.
+ */
+#define SOCK_CLOSING 0x1A
+
+/**
+ * @brief Closing state
+ * @details These indicate Socket n is closing.\n
+ * These are shown in disconnect-process such as active-close and passive-close.\n
+ * When Disconnect-process is successfully completed, or when timeout occurs, these change to \ref SOCK_CLOSED.
+ */
+#define SOCK_TIME_WAIT 0x1B
+
+/**
+ * @brief Closing state
+ * @details This indicates Socket n received the disconnect-request (FIN packet) from the connected peer.\n
+ * This is half-closing status, and data can be transferred.\n
+ * For full-closing, DISCON command is used. But For just-closing, CLOSE command is used.
+ */
+#define SOCK_CLOSE_WAIT 0x1C
+
+/**
+ * @brief Closing state
+ * @details This indicates Socket n is waiting for the response (FIN/ACK packet) to the disconnect-request (FIN packet) by passive-close.\n
+ * It changes to \ref SOCK_CLOSED when Socket n received the response successfully, or when timeout occurs (\ref Sn_IR[TIMEOUT] = '1').
+ */
+#define SOCK_LAST_ACK 0x1D
+
+/**
+ * @brief UDP socket
+ * @details This indicates Socket n is opened in UDP mode(Sn_MR(P[3:0]) = 010).\n
+ * It changes to SOCK_UDP when Sn_MR(P[3:0]) = 010 and OPEN command is ordered.\n
+ * Unlike TCP mode, data can be transfered without the connection-process.
+ */
+#define SOCK_UDP 0x22 ///< udp socket
+
+/**
+* @brief IP raw mode socket
+ * @details TThe socket is opened in IPRAW mode. The SOCKET status is change to SOCK_IPRAW when Sn_MR (P3:P0) is
+ * Sn_MR_IPRAW and OPEN command is used.\n
+ * IP Packet can be transferred without a connection similar to the UDP mode.
+*/
+#define SOCK_IPRAW 0x32 ///< ip raw mode socket
+
+/**
+ * @brief MAC raw mode socket
+ * @details This indicates Socket 0 is opened in MACRAW mode (S0_MR(P[3:0]) = 100and is valid only in Socket 0.\n
+ * It changes to SOCK_MACRAW when S0_MR(P[3:0] = 100)and OPEN command is ordered.\n
+ * Like UDP mode socket, MACRAW mode Socket 0 can transfer a MAC packet (Ethernet frame) without the connection-process.
+ */
+#define SOCK_MACRAW 0x42 ///< mac raw mode socket
+
+/**
+ * @brief PPPoE mode socket
+ * @details It is the status that SOCKET0 is open as PPPoE mode. It is changed to SOCK_PPPoE in case of S0_CR=OPEN and S0_MR
+ * (P3:P0)=S0_MR_PPPoE.\n
+ * It is temporarily used at the PPPoE
+connection.
+ */
+#define SOCK_PPPOE 0x5F ///< pppoe socket
+
+// IP PROTOCOL
+#define IPPROTO_IP 0 ///< Dummy for IP
+#define IPPROTO_ICMP 1 ///< Control message protocol
+#define IPPROTO_IGMP 2 ///< Internet group management protocol
+#define IPPROTO_GGP 3 ///< GW^2 (deprecated)
+#define IPPROTO_TCP 6 ///< TCP
+#define IPPROTO_PUP 12 ///< PUP
+#define IPPROTO_UDP 17 ///< UDP
+#define IPPROTO_IDP 22 ///< XNS idp
+#define IPPROTO_ND 77 ///< UNOFFICIAL net disk protocol
+#define IPPROTO_RAW 255 ///< Raw IP packet
+
+/**
+ * @brief Enter a critical section
+ *
+ * @details It is provided to protect your shared code which are executed without distribution. \n \n
+ *
+ * In non-OS environment, It can be just implemented by disabling whole interrupt.\n
+ * In OS environment, You can replace it to critical section api supported by OS.
+ *
+ * \sa WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF()
+ * \sa WIZCHIP_CRITICAL_EXIT()
+ */
+#define WIZCHIP_CRITICAL_ENTER() WIZCHIP.CRIS._enter()
+
+#ifdef _exit
+#undef _exit
+#endif
+
+/**
+ * @brief Exit a critical section
+ *
+ * @details It is provided to protect your shared code which are executed without distribution. \n\n
+ *
+ * In non-OS environment, It can be just implemented by disabling whole interrupt. \n
+ * In OS environment, You can replace it to critical section api supported by OS.
+ *
+ * @sa WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF()
+ * @sa WIZCHIP_CRITICAL_ENTER()
+ */
+#define WIZCHIP_CRITICAL_EXIT() WIZCHIP.CRIS._exit()
+
+
+
+////////////////////////
+// Basic I/O Function //
+////////////////////////
+/**
+ * @ingroup Basic_IO_function_W5200
+ * @brief It reads 1 byte value from a register.
+ * @param AddrSel Register address
+ * @return The value of register
+ */
+uint8_t WIZCHIP_READ (uint32_t AddrSel);
+
+/**
+ * @ingroup Basic_IO_function_W5200
+ * @brief It writes 1 byte value to a register.
+ * @param AddrSel Register address
+ * @param wb Write data
+ * @return void
+ */
+void WIZCHIP_WRITE(uint32_t AddrSel, uint8_t wb );
+
+/**
+ * @ingroup Basic_IO_function_W5200
+ * @brief It reads sequence data from registers.
+ * @param AddrSel Register address
+ * @param pBuf Pointer buffer to read data
+ * @param len Data length
+ */
+void WIZCHIP_READ_BUF (uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
+
+/**
+ * @ingroup Basic_IO_function_W5200
+ * @brief It writes sequence data to registers.
+ * @param AddrSel Register address
+ * @param pBuf Pointer buffer to write data
+ * @param len Data length
+ */
+void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
+
+
+/////////////////////////////////
+// Common Register IO function //
+/////////////////////////////////
+
+/**
+ * @ingroup Common_register_access_function_W5200
+ * @brief Set Mode Register
+ * @param (uint8_t)mr The value to be set.
+ * @sa getMR()
+ */
+#if (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_)
+ #define setMR(mr) WIZCHIP_WRITE(MR,mr)
+#else
+ #define setMR(mr) (*((uint8_t*)MR) = mr)
+#endif
+
+/**
+ * @ingroup Common_register_access_function_W5200
+ * @brief Get @ref MR.
+ * @return uint8_t. The value of Mode register.
+ * @sa setMR()
+ */
+#if (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_)
+ #define getMR() WIZCHIP_READ(MR)
+#else
+ #define getMR() (*(uint8_t*)MR)
+#endif
+
+/**
+ * @ingroup Common_register_access_function_W5200
+ * @brief Set @ref GAR.
+ * @param (uint8_t*)gar Pointer variable to set gateway IP address. It should be allocated 4 bytes.
+ * @sa getGAR()
+ */
+#define setGAR(gar) \
+ WIZCHIP_WRITE_BUF(GAR,gar,4)
+
+/**
+ * @ingroup Common_register_access_function_W5200
+ * @brief Get @ref GAR.
+ * @param (uint8_t*)gar Pointer variable to get gateway IP address. It should be allocated 4 bytes.
+ * @sa setGAR()
+ */
+#define getGAR(gar) \
+ WIZCHIP_READ_BUF(GAR,gar,4)
+
+/**
+ * @ingroup Common_register_access_function_W5200
+ * @brief Set @ref SUBR.
+ * @param (uint8_t*)subr Pointer variable to set subnet mask address. It should be allocated 4 bytes.
+ * @note If subr is null pointer, set the backup subnet to SUBR. \n
+ * If subr is 0.0.0.0, back up SUBR and clear it. \n
+ * Otherwize, set subr to SUBR
+ * @sa getSUBR()
+ */
+#define setSUBR(subr) \
+ WIZCHIP_WRITE_BUF(SUBR, subr,4)
+
+/**
+ * @ingroup Common_register_access_function_W5200
+ * @brief Get @ref SUBR.
+ * @param (uint8_t*)subr Pointer variable to get subnet mask address. It should be allocated 4 bytes.
+ * @sa setSUBR()
+ */
+#define getSUBR(subr) \
+ WIZCHIP_READ_BUF(SUBR, subr, 4)
+
+/**
+ * @ingroup Common_register_access_function_W5200
+ * @brief Set @ref SHAR.
+ * @param (uint8_t*)shar Pointer variable to set local MAC address. It should be allocated 6 bytes.
+ * @sa getSHAR()
+ */
+#define setSHAR(shar) \
+ WIZCHIP_WRITE_BUF(SHAR, shar, 6)
+
+/**
+ * @ingroup Common_register_access_function_W5200
+ * @brief Get @ref SHAR.
+ * @param (uint8_t*)shar Pointer variable to get local MAC address. It should be allocated 6 bytes.
+ * @sa setSHAR()
+ */
+#define getSHAR(shar) \
+ WIZCHIP_READ_BUF(SHAR, shar, 6)
+
+/**
+ * @ingroup Common_register_access_function_W5200
+ * @brief Set @ref SIPR.
+ * @param (uint8_t*)sipr Pointer variable to set local IP address. It should be allocated 4 bytes.
+ * @sa getSIPR()
+*/
+#define setSIPR(sipr) \
+ WIZCHIP_WRITE_BUF(SIPR, sipr, 4)
+
+/**
+ * @ingroup Common_register_access_function_W5200
+ * @brief Get @ref SIPR.
+ * @param (uint8_t*)sipr Pointer variable to get local IP address. It should be allocated 4 bytes.
+ * @sa setSIPR()
+ */
+#define getSIPR(sipr) \
+ WIZCHIP_READ_BUF(SIPR, sipr, 4)
+
+/**
+ * @ingroup Common_register_access_function_W5200
+ * @brief Set \ref IR register
+ * @param (uint8_t)ir Value to set \ref IR register.
+ * @sa getIR()
+ */
+#define setIR(ir) \
+ WIZCHIP_WRITE(IR, (ir & 0xA0))
+/**
+ * @ingroup Common_register_access_function_W5200
+ * @brief Get \ref IR register
+ * @return uint8_t. Value of \ref IR register.
+ * @sa setIR()
+ */
+#define getIR() \
+ (WIZCHIP_READ(IR) & 0xA0)
+
+/**
+ * @ingroup Common_register_access_function_W5200
+ * @brief Set \ref IMR2 register
+ * @param (uint8_t)imr Value to set @ref IMR2 register.
+ * @sa getIMR()
+ */
+//M20150410 : Replace _IMR_ with IMR2 for integrating with ioLibrary
+/*
+#define setIMR(imr) \
+ WIZCHIP_WRITE(_IMR_, imr)
+*/
+#define setIMR(imr) \
+ WIZCHIP_WRITE(IMR2, imr & 0xA0)
+
+/**
+ * @ingroup Common_register_access_function_W5200
+ * @brief Get \ref IMR2 register
+ * @return uint8_t. Value of @ref IMR2 register.
+ * @sa setIMR()
+ */
+//M20150410 : Replace _IMR_ with IMR2 for integrating with ioLibrary
+/*
+#define getIMR() \
+ WIZCHIP_READ(_IMR_)
+*/
+#define getIMR() \
+ (WIZCHIP_READ(IMR2) & 0xA0)
+
+/**
+ * @ingroup Common_register_access_function_W5200
+ * @brief Set \ref _RTR_ register
+ * @param (uint16_t)rtr Value to set @ref _RTR_ register.
+ * @sa getRTR()
+ */
+#define setRTR(rtr) {\
+ WIZCHIP_WRITE(_RTR_, (uint8_t)(rtr >> 8)); \
+ WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(_RTR_,1), (uint8_t) rtr); \
+ }
+
+/**
+ * @ingroup Common_register_access_function_W5200
+ * @brief Get \ref _RTR_ register
+ * @return uint16_t. Value of @ref _RTR_ register.
+ * @sa setRTR()
+ */
+#define getRTR() \
+ (((uint16_t)WIZCHIP_READ(_RTR_) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(_RTR_,1)))
+
+/**
+ * @ingroup Common_register_access_function_W5200
+ * @brief Set \ref _RCR_ register
+ * @param (uint8_t)rcr Value to set @ref _RCR_ register.
+ * @sa getRCR()
+ */
+#define setRCR(rcr) \
+ WIZCHIP_WRITE(_RCR_, rcr)
+
+/**
+ * @ingroup Common_register_access_function_W5200
+ * @brief Get \ref _RCR_ register
+ * @return uint8_t. Value of @ref _RCR_ register.
+ * @sa setRCR()
+ */
+#define getRCR() \
+ WIZCHIP_READ(_RCR_)
+
+/**
+ * @ingroup Common_register_access_function_W5200
+ * @brief Get \ref PATR register
+ * @return uint16_t. Value to set \ref PATR register
+ */
+#define getPATR() \
+ (((uint16_t)WIZCHIP_READ(PATR) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(PATR,1)))
+
+/**
+ * @ingroup Common_register_access_function_W5200
+ * @brief Get \ref PPPALGO register
+ * @return uint8_t. Value to set \ref PPPALGO register
+ */
+#define getPPPALGO() \
+ WIZCHIP_READ(PPPALGO)
+
+
+/**
+ * @ingroup Common_register_access_function_W5200
+ * @brief Get \ref VERSIONR register
+ * @return uint8_t. Value to set \ref VERSIONR register
+ */
+#define getVERSIONR() \
+ WIZCHIP_READ(VERSIONR)
+
+/**
+ * @ingroup Common_register_access_function_W5200
+ * @brief Set \ref PTIMER register
+ * @param (uint8_t)ptimer Value to set \ref PTIMER register.
+ * @sa getPTIMER()
+ */
+#define setPTIMER(ptimer) \
+ WIZCHIP_WRITE(PTIMER, ptimer)
+
+/**
+ * @ingroup Common_register_access_function_W5200
+ * @brief Get \ref PTIMER register
+ * @return uint8_t. Value of @ref PTIMER register.
+ * @sa setPTIMER()
+ */
+#define getPTIMER() \
+ WIZCHIP_READ(PTIMER)
+
+/**
+ * @ingroup Common_register_access_function_W5200
+ * @brief Set \ref PMAGIC register
+ * @param (uint8_t)pmagic Value to set @ref PMAGIC register.
+ * @sa getPMAGIC()
+ */
+#define setPMAGIC(pmagic) \
+ WIZCHIP_WRITE(PMAGIC, pmagic)
+
+/**
+ * @ingroup Common_register_access_function_W5200
+ * @brief Get \ref PMAGIC register
+ * @return uint8_t. Value of @ref PMAGIC register.
+ * @sa setPMAGIC()
+ */
+#define getPMAGIC() \
+ WIZCHIP_READ(PMAGIC)
+
+/**
+ * @ingroup Common_register_access_function_W5200
+ * @brief Set @ref INTLEVEL register
+ * @param (uint16_t)intlevel Value to set @ref INTLEVEL register.
+ * @sa getINTLEVEL()
+ */
+#define setINTLEVEL(intlevel) {\
+ WIZCHIP_WRITE(INTLEVEL, (uint8_t)(intlevel >> 8)); \
+ WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(INTLEVEL,1), (uint8_t) intlevel); \
+ }
+/**
+ * @ingroup Common_register_access_function_W5200
+ * @brief Get @ref INTLEVEL register
+ * @return uint16_t. Value of @ref INTLEVEL register.
+ * @sa setINTLEVEL()
+ */
+#define getINTLEVEL() \
+ (((uint16_t)WIZCHIP_READ(INTLEVEL) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(INTLEVEL,1)))
+
+/**
+ * @ingroup Common_register_access_function_W5200
+ * @brief Set \ref IR2 register
+ * @param (uint8_t)ir2 Value to set \ref IR2 register.
+ * @sa getIR2()
+ */
+#define setIR2(ir2) \
+ WIZCHIP_WRITE(IR2, ir2)
+#define setSIR(ir2) setIR2(ir2)
+
+/**
+ * @ingroup Common_register_access_function_W5200
+ * @brief Get \ref IR2 register
+ * @return uint8_t. Value of \ref IR2 register.
+ * @sa setIR2()
+ */
+#define getIR2() \
+ WIZCHIP_READ(IR2)
+#define getSIR() getIR2()
+
+/**
+ * @ingroup Common_register_access_function_W5200
+ * @brief Get \ref PHYSTATUS register
+ * @return uint8_t. Value to set \ref PHYSTATUS register.
+ */
+#define getPHYSTATUS() \
+ WIZCHIP_READ(PHYSTATUS)
+
+/**
+ * @ingroup Common_register_access_function_W5200
+ * @brief Set \ref _IMR_ register
+ * @param (uint8_t)imr2 Value to set \ref IMR2 register.
+ * @sa getIMR2()
+ * @note If possible, Don't use this function. Instead, Use setSIMR() for compatible with ioLibrary.
+ */
+ //M20150410 : Replace IMR2 with _IMR_ for integrating with ioLibrary
+/*
+#define setIMR2(imr2) \
+ WIZCHIP_WRITE(IMR2, (imr2 & 0xA0))
+*/
+#define setIMR2(imr2) \
+ WIZCHIP_WRITE(_IMR_, imr2)
+#define setSIMR(imr2) setIMR2(imr2)
+
+/**
+ * @ingroup Common_register_access_function_W5200
+ * @brief Get \ref _IMR_ register
+ * @return uint8_t. Value of \ref IMR2 register.
+ * @sa setIMR2()
+ */
+ //M20150410 : Replace IMR2 with _IMR_ for integrating with ioLibrary
+/*
+#define getIMR2() \
+ (WIZCHIP_READ(IMR2) & 0xA0)
+*/
+#define getIMR2() \
+ WIZCHIP_READ(_IMR_)
+#define getSIMR() getIMR2()
+///////////////////////////////////
+// Socket N register I/O function //
+///////////////////////////////////
+/**
+ * @ingroup Socket_register_access_function_W5200
+ * @brief Set @ref Sn_MR register
+ * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_ expect bit 4.
+ * @param mr Value to set @ref Sn_MR
+ * @sa getSn_MR()
+ */
+#define setSn_MR(sn, mr) \
+ WIZCHIP_WRITE(Sn_MR(sn),mr)
+
+/**
+ * @ingroup Socket_register_access_function_W5200
+ * @brief Get @ref Sn_MR register
+ * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_ expect bit 4.
+ * @return Value of @ref Sn_MR.
+ * @sa setSn_MR()
+ */
+#define getSn_MR(sn) \
+ WIZCHIP_READ(Sn_MR(sn))
+
+/**
+ * @ingroup Socket_register_access_function_W5200
+ * @brief Set @ref Sn_CR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param (uint8_t)cr Value to set @ref Sn_CR
+ * @sa getSn_CR()
+ */
+#define setSn_CR(sn, cr) \
+ WIZCHIP_WRITE(Sn_CR(sn), cr)
+
+/**
+ * @ingroup Socket_register_access_function_W5200
+ * @brief Get @ref Sn_CR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint8_t. Value of @ref Sn_CR.
+ * @sa setSn_CR()
+ */
+#define getSn_CR(sn) \
+ WIZCHIP_READ(Sn_CR(sn))
+
+/**
+ * @ingroup Socket_register_access_function_W5200
+ * @brief Set @ref Sn_IR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param (uint8_t)ir Value to set @ref Sn_IR
+ * @sa getSn_IR()
+ */
+#define setSn_IR(sn, ir) \
+ WIZCHIP_WRITE(Sn_IR(sn), ir)
+
+/**
+ * @ingroup Socket_register_access_function_W5200
+ * @brief Get @ref Sn_IR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint8_t. Value of @ref Sn_IR.
+ * @sa setSn_IR()
+ */
+#define getSn_IR(sn) \
+ WIZCHIP_READ(Sn_IR(sn))
+
+/**
+ * @ingroup Socket_register_access_function_W5200
+ * @brief Set @ref Sn_IMR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param (uint8_t)imr Value to set @ref Sn_IMR
+ * @sa getSn_IMR()
+*/
+#define setSn_IMR(sn, imr) \
+ WIZCHIP_WRITE(Sn_IMR(sn), imr)
+
+/**
+ * @ingroup Socket_register_access_function_W5200
+ * @brief Get @ref Sn_IMR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint8_t. Value of @ref Sn_IMR.
+ * @sa setSn_IMR()
+ */
+#define getSn_IMR(sn) \
+ WIZCHIP_READ(Sn_IMR(sn))
+
+/**
+ * @ingroup Socket_register_access_function_W5200
+ * @brief Get @ref Sn_SR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint8_t. Value of @ref Sn_SR.
+ */
+#define getSn_SR(sn) \
+ WIZCHIP_READ(Sn_SR(sn))
+
+/**
+ * @ingroup Socket_register_access_function_W5200
+ * @brief Set @ref Sn_PORT register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param (uint16_t)port Value to set @ref Sn_PORT.
+ * @sa getSn_PORT()
+ */
+#define setSn_PORT(sn, port) { \
+ WIZCHIP_WRITE(Sn_PORT(sn), (uint8_t)(port >> 8)); \
+ WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_PORT(sn),1), (uint8_t) port); \
+ }
+
+/**
+ * @ingroup Socket_register_access_function_W5200
+ * @brief Get @ref Sn_PORT register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint16_t. Value of @ref Sn_PORT.
+ * @sa setSn_PORT()
+ */
+#define getSn_PORT(sn) \
+ (((uint16_t)WIZCHIP_READ(Sn_PORT(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_PORT(sn),1)))
+
+/**
+ * @ingroup Socket_register_access_function_W5200
+ * @brief Set @ref Sn_DHAR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param (uint8_t*)dhar Pointer variable to set socket n destination hardware address. It should be allocated 6 bytes.
+ * @sa getSn_DHAR()
+ */
+#define setSn_DHAR(sn, dhar) \
+ WIZCHIP_WRITE_BUF(Sn_DHAR(sn), dhar, 6)
+
+/**
+ * @ingroup Socket_register_access_function_W5200
+ * @brief Get @ref Sn_DHAR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param (uint8_t*)dhar Pointer variable to get socket n destination hardware address. It should be allocated 6 bytes.
+ * @sa setSn_DHAR()
+ */
+#define getSn_DHAR(sn, dhar) \
+ WIZCHIP_READ_BUF(Sn_DHAR(sn), dhar, 6)
+
+/**
+ * @ingroup Socket_register_access_function_W5200
+ * @brief Set @ref Sn_DIPR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param (uint8_t*)dipr Pointer variable to set socket n destination IP address. It should be allocated 4 bytes.
+ * @sa getSn_DIPR()
+ */
+#define setSn_DIPR(sn, dipr) \
+ WIZCHIP_WRITE_BUF(Sn_DIPR(sn), dipr, 4)
+
+/**
+ * @ingroup Socket_register_access_function_W5200
+ * @brief Get @ref Sn_DIPR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param (uint8_t*)dipr Pointer variable to get socket n destination IP address. It should be allocated 4 bytes.
+ * @sa SetSn_DIPR()
+ */
+#define getSn_DIPR(sn, dipr) \
+ WIZCHIP_READ_BUF(Sn_DIPR(sn), dipr, 4)
+
+/**
+ * @ingroup Socket_register_access_function_W5200
+ * @brief Set @ref Sn_DPORT register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param (uint16_t)dport Value to set @ref Sn_DPORT
+ * @sa getSn_DPORT()
+ */
+#define setSn_DPORT(sn, dport) { \
+ WIZCHIP_WRITE(Sn_DPORT(sn), (uint8_t) (dport>>8)); \
+ WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_DPORT(sn),1), (uint8_t) dport); \
+ }
+
+/**
+ * @ingroup Socket_register_access_function_W5200
+ * @brief Get @ref Sn_DPORT register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint16_t. Value of @ref Sn_DPORT.
+ * @sa setSn_DPORT()
+ */
+#define getSn_DPORT(sn) \
+ (((uint16_t)WIZCHIP_READ(Sn_DPORT(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_DPORT(sn),1)))
+
+/**
+ * @ingroup Socket_register_access_function_W5200
+ * @brief Set @ref Sn_MSSR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param (uint16_t)mss Value to set @ref Sn_MSSR
+ * @sa setSn_MSSR()
+ */
+#define setSn_MSSR(sn, mss) { \
+ WIZCHIP_WRITE(Sn_MSSR(sn), (uint8_t)(mss>>8)); \
+ WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_MSSR(sn),1), (uint8_t) mss); \
+ }
+
+/**
+ * @ingroup Socket_register_access_function_W5200
+ * @brief Get @ref Sn_MSSR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint16_t. Value of @ref Sn_MSSR.
+ * @sa setSn_MSSR()
+ */
+#define getSn_MSSR(sn) \
+ (((uint16_t)WIZCHIP_READ(Sn_MSSR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_MSSR(sn),1)))
+
+/**
+ * @ingroup Socket_register_access_function_W5200
+ * @brief Set @ref Sn_PROTO register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param (uint8_t)proto Value to set \ref Sn_PROTO
+ * @sa getSn_PROTO()
+ */
+//M20150601 : Fixed Wrong Register address
+/*
+#define setSn_PROTO(sn, proto) \
+ WIZCHIP_WRITE(Sn_TOS(sn), tos)
+*/
+#define setSn_PROTO(sn, proto) \
+ WIZCHIP_WRITE(Sn_PROTO(sn), proto)
+
+/**
+ * @ingroup Socket_register_access_function_W5200
+ * @brief Get @ref Sn_PROTO register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint8_t. Value of @ref Sn_PROTO.
+ * @sa setSn_PROTO()
+ */
+//M20150601 : Fixed Wrong Register address
+/*
+#define getSn_PROTO(sn) \
+ WIZCHIP_READ(Sn_TOS(sn))
+*/
+#define getSn_PROTO(sn) \
+ WIZCHIP_READ(Sn_PROTO(sn))
+
+/**
+ * @ingroup Socket_register_access_function_W5200
+ * @brief Set @ref Sn_TOS register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param (uint8_t)tos Value to set @ref Sn_TOS
+ * @sa getSn_TOS()
+ */
+#define setSn_TOS(sn, tos) \
+ WIZCHIP_WRITE(Sn_TOS(sn), tos)
+
+/**
+ * @ingroup Socket_register_access_function_W5200
+ * @brief Get @ref Sn_TOS register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_ .
+ * @return uint8_t. Value of Sn_TOS.
+ * @sa setSn_TOS()
+ */
+#define getSn_TOS(sn) \
+ WIZCHIP_READ(Sn_TOS(sn))
+
+/**
+ * @ingroup Socket_register_access_function_W5200
+ * @brief Set @ref Sn_TTL register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_ .
+ * @param (uint8_t)ttl Value to set @ref Sn_TTL
+ * @sa getSn_TTL()
+ */
+#define setSn_TTL(sn, ttl) \
+ WIZCHIP_WRITE(Sn_TTL(sn), ttl)
+
+/**
+ * @ingroup Socket_register_access_function_W5200
+ * @brief Get @ref Sn_TTL register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_ .
+ * @return uint8_t. Value of @ref Sn_TTL.
+ * @sa setSn_TTL()
+ */
+#define getSn_TTL(sn) \
+ WIZCHIP_READ(Sn_TTL(sn))
+
+/**
+ * @ingroup Socket_register_access_function_W5200
+ * @brief Set @ref Sn_RXMEM_SIZE register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_ .
+ * @param (uint8_t)rxmemsize Value to set \ref Sn_RXMEM_SIZE
+ * @sa getSn_RXMEM_SIZE()
+ */
+#define setSn_RXMEM_SIZE(sn, rxmemsize) \
+ WIZCHIP_WRITE(Sn_RXMEM_SIZE(sn),rxmemsize)
+
+#define setSn_RXBUF_SIZE(sn,rxmemsize) setSn_RXMEM_SIZE(sn,rxmemsize)
+
+/**
+ * @ingroup Socket_register_access_function_W5200
+ * @brief Get @ref Sn_RXMEM_SIZE register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint8_t. Value of @ref Sn_RXMEM.
+ * @sa setSn_RXMEM_SIZE()
+ */
+#define getSn_RXMEM_SIZE(sn) \
+ WIZCHIP_READ(Sn_RXMEM_SIZE(sn))
+
+#define getSn_RXBUF_SIZE(sn) getSn_RXMEM_SIZE(sn)
+
+/**
+ * @ingroup Socket_register_access_function_W5200
+ * @brief Set @ref Sn_TXMEM_SIZE register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param (uint8_t)txmemsize Value to set \ref Sn_TXMEM_SIZE
+ * @sa getSn_TXMEM_SIZE()
+ */
+#define setSn_TXMEM_SIZE(sn, txmemsize) \
+ WIZCHIP_WRITE(Sn_TXMEM_SIZE(sn), txmemsize)
+
+#define setSn_TXBUF_SIZE(sn, txmemsize) setSn_TXMEM_SIZE(sn,txmemsize)
+
+/**
+ * @ingroup Socket_register_access_function_W5200
+ * @brief Get @ref Sn_TXMEM_SIZE register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint8_t. Value of @ref Sn_TXMEM_SIZE.
+ * @sa setSn_TXMEM_SIZE()
+ */
+#define getSn_TXMEM_SIZE(sn) \
+ WIZCHIP_READ(Sn_TXMEM_SIZE(sn))
+
+#define getSn_TXBUF_SIZE(sn) getSn_TXMEM_SIZE(sn)
+
+/**
+ * @ingroup Socket_register_access_function_W5200
+ * @brief Get @ref Sn_TX_FSR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint16_t. Value of @ref Sn_TX_FSR.
+ */
+uint16_t getSn_TX_FSR(uint8_t sn);
+
+/**
+ * @ingroup Socket_register_access_function_W5200
+ * @brief Get @ref Sn_TX_RD register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint16_t. Value of @ref Sn_TX_RD.
+ */
+#define getSn_TX_RD(sn) \
+ (((uint16_t)WIZCHIP_READ(Sn_TX_RD(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_RD(sn),1)))
+
+/**
+ * @ingroup Socket_register_access_function_W5200
+ * @brief Set @ref Sn_TX_WR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param (uint16_t)txwr Value to set @ref Sn_TX_WR
+ * @sa GetSn_TX_WR()
+ */
+#define setSn_TX_WR(sn, txwr) { \
+ WIZCHIP_WRITE(Sn_TX_WR(sn), (uint8_t)(txwr>>8)); \
+ WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_TX_WR(sn),1), (uint8_t) txwr); \
+ }
+
+/**
+ * @ingroup Socket_register_access_function_W5200
+ * @brief Get @ref Sn_TX_WR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint16_t. Value of @ref Sn_TX_WR.
+ * @sa setSn_TX_WR()
+ */
+#define getSn_TX_WR(sn) \
+ (((uint16_t)WIZCHIP_READ(Sn_TX_WR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_WR(sn),1)))
+
+/**
+ * @ingroup Socket_register_access_function_W5200
+ * @brief Get @ref Sn_RX_RSR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint16_t. Value of @ref Sn_RX_RSR.
+ */
+uint16_t getSn_RX_RSR(uint8_t sn);
+
+/**
+ * @ingroup Socket_register_access_function_W5200
+ * @brief Set @ref Sn_RX_RD register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param (uint16_t)rxrd Value to set @ref Sn_RX_RD
+ * @sa getSn_RX_RD()
+ */
+#define setSn_RX_RD(sn, rxrd) { \
+ WIZCHIP_WRITE(Sn_RX_RD(sn), (uint8_t)(rxrd>>8)); \
+ WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_RX_RD(sn),1), (uint8_t) rxrd); \
+ }
+
+/**
+ * @ingroup Socket_register_access_function_W5200
+ * @brief Get @ref Sn_RX_RD register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint16_t. Value of @ref Sn_RX_RD.
+ * @sa setSn_RX_RD()
+ */
+#define getSn_RX_RD(sn) \
+ (((uint16_t)WIZCHIP_READ(Sn_RX_RD(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RD(sn),1)))
+
+/**
+ * @ingroup Socket_register_access_function_W5200
+ * @brief Set @ref Sn_RX_WR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param (uint16_t)rxwr Value to set \ref Sn_RX_WR
+ * @sa getSn_RX_WR()
+ */
+#define setSn_RX_WR(sn, rxwr) { \
+ WIZCHIP_WRITE(Sn_RX_WR(sn), (uint8_t)(rxwr>>8)); \
+ WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_RX_WR(sn),1), (uint8_t) rxwr); \
+ }
+
+
+/**
+ * @ingroup Socket_register_access_function_W5200
+ * @brief Get @ref Sn_RX_WR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint16_t. Value of @ref Sn_RX_WR.
+ */
+#define getSn_RX_WR(sn) \
+ (((uint16_t)WIZCHIP_READ(Sn_RX_WR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_WR(sn),1)))
+
+/**
+ * @ingroup Socket_register_access_function_W5200
+ * @brief Set @ref Sn_IMR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param (uint8_t)imr Value to set \ref Sn_IMR
+ * @sa getSn_IMR()
+ */
+#define setSn_IMR(sn ,imr) \
+ WIZCHIP_WRITE(Sn_IMR(sn), imr)
+
+/**
+ * @ingroup Socket_register_access_function_W5200
+ * @brief Get @ref Sn_IMR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint8_t. Value of @ref Sn_IMR.
+ * @sa setSn_IMR()
+ */
+#define getSn_IMR(sn) \
+ WIZCHIP_READ(Sn_IMR(sn))
+
+/**
+ * @ingroup Socket_register_access_function_W5200
+ * @brief Set @ref Sn_FRAG register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param (uint16_t)frag Value to set \ref Sn_FRAG
+ * @sa getSn_FRAG()
+ */
+#define setSn_FRAG(sn, frag) { \
+ WIZCHIP_WRITE(Sn_FRAG(sn), (uint8_t)(frag >>8)); \
+ WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_FRAG(sn),1), (uint8_t) frag); \
+ }
+
+/**
+ * @ingroup Socket_register_access_function_W5200
+ * @brief Get @ref Sn_FRAG register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint16_t. Value of @ref Sn_FRAG.
+ * @sa setSn_FRAG()
+ */
+#define getSn_FRAG(sn) \
+ (((uint16_t)WIZCHIP_READ(Sn_FRAG(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_FRAG(sn),1)))
+
+/**
+ * @ingroup Socket_register_access_function_W5200
+ * @brief Get the max RX buffer size of socket sn
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint16_t. Max buffer size
+ */
+#define getSn_RxMAX(sn) \
+ ((uint16_t)getSn_RXMEM_SIZE(sn) << 10)
+
+/**
+ * @ingroup Socket_register_access_function_W5200
+ * @brief Get the max TX buffer size of socket sn
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint16_t. Max buffer size
+ */
+#define getSn_TxMAX(sn) \
+ ((uint16_t)getSn_TXMEM_SIZE(sn) << 10)
+
+/**
+ * @ingroup Socket_register_access_function_W5200
+ * @brief Get the mask of socket sn RX buffer.
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint16_t. Mask value
+ */
+#define getSn_RxMASK(sn) \
+ ((uint16_t)getSn_RxMAX(sn) - 1)
+
+/**
+ * @ingroup Socket_register_access_function_W5200
+ * @brief Get the mask of socket sn TX buffer
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint16_t. Mask value
+ */
+#define getSn_TxMASK(sn) \
+ ((uint16_t)getSn_TxMAX(sn) - 1)
+
+/**
+ * @ingroup Socket_register_access_function_W5200
+ * @brief Get the base address of socket sn RX buffer.
+ * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint16_t. Value of Socket n RX buffer base address.
+ */
+uint16_t getSn_RxBASE(uint8_t sn);
+
+/**
+ * @ingroup Socket_register_access_function_W5200
+ * @brief Get the base address of socket sn TX buffer.
+ * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint16_t. Value of Socket n TX buffer base address.
+ */
+uint16_t getSn_TxBASE(uint8_t sn);
+
+/////////////////////////////////////
+// Sn_TXBUF & Sn_RXBUF IO function //
+/////////////////////////////////////
+/**
+ * @ingroup Basic_IO_function_W5200
+ * @brief It copies data to internal TX memory
+ *
+ * @details This function reads the Tx write pointer register and after that,
+ * it copies the wizdata(pointer buffer) of the length of len(variable) bytes to internal TX memory
+ * and updates the Tx write pointer register.
+ * This function is being called by send() and sendto() function also.
+ *
+ * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param wizdata Pointer buffer to write data
+ * @param len Data length
+ * @sa wiz_recv_data()
+ */
+void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint16_t len);
+
+/**
+ * @ingroup Basic_IO_function_W5200
+ * @brief It copies data to your buffer from internal RX memory
+ *
+ * @details This function read the Rx read pointer register and after that,
+ * it copies the received data from internal RX memory
+ * to wizdata(pointer variable) of the length of len(variable) bytes.
+ * This function is being called by recv() also.
+ *
+ * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param wizdata Pointer buffer to read data
+ * @param len Data length
+ * @sa wiz_send_data()
+ */
+void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len);
+
+/**
+ * @ingroup Basic_IO_function_W5200
+ * @brief It discard the received data in RX memory.
+ * @details It discards the data of the length of len(variable) bytes in internal RX memory.
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param len Data length
+ */
+void wiz_recv_ignore(uint8_t sn, uint16_t len);
+
+/// \cond DOXY_APPLY_CODE
+#endif
+/// \endcond
+
+#endif //_W5200_H_
+
+
+
diff --git a/Libraries/ioLibrary_Driver/Ethernet/W5300/w5300.c b/Libraries/ioLibrary_Driver/Ethernet/W5300/w5300.c
new file mode 100644
index 0000000..4b5e60b
--- /dev/null
+++ b/Libraries/ioLibrary_Driver/Ethernet/W5300/w5300.c
@@ -0,0 +1,225 @@
+//*****************************************************************************
+//
+//! \file w5300.h
+//! \brief W5300 HAL implement File.
+//! \version 1.0.0
+//! \date 2015/05/01
+//! \par Revision history
+//! <2015/05/01> 1st Released for integrating with ioLibrary
+//! Download the latest version directly from GitHub. Please visit the our GitHub repository for ioLibrary.
+//! >> https://github.com/Wiznet/ioLibrary_Driver
+//! \author MidnightCow
+//! \copyright
+//!
+//! Copyright (c) 2015, WIZnet Co., LTD.
+//! All rights reserved.
+//!
+//! Redistribution and use in source and binary forms, with or without
+//! modification, are permitted provided that the following conditions
+//! are met:
+//!
+//! * Redistributions of source code must retain the above copyright
+//! notice, this list of conditions and the following disclaimer.
+//! * Redistributions in binary form must reproduce the above copyright
+//! notice, this list of conditions and the following disclaimer in the
+//! documentation and/or other materials provided with the distribution.
+//! * Neither the name of the nor the names of its
+//! contributors may be used to endorse or promote products derived
+//! from this software without specific prior written permission.
+//!
+//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+//! THE POSSIBILITY OF SUCH DAMAGE.
+//
+//*****************************************************************************
+
+#include
+#include "wizchip_conf.h"
+
+#if _WIZCHIP_ == 5300
+
+ extern uint8_t sock_remained_byte[_WIZCHIP_SOCK_NUM_];
+ extern uint8_t sock_pack_info[_WIZCHIP_SOCK_NUM_];
+
+
+/***********************
+ * Basic I/O Function *
+ ***********************/
+
+void WIZCHIP_WRITE(uint32_t AddrSel, uint16_t wb )
+{
+ WIZCHIP_CRITICAL_ENTER();
+ WIZCHIP.CS._select();
+
+#if ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_DIR_) )
+ #if(_WIZCHIP_IO_BUS_WIDTH_ == 8)
+ WIZCHIP.IF.BUS._write_data(AddrSel, (uint8_t)(wb>>8));
+ WIZCHIP.IF.BUS._write_data(WIZCHIP_OFFSET_INC(AddrSel,1),(uint8_t)wb);
+ #elif(_WIZCHIP_IO_BUS_WIDTH_ == 16)
+ WIZCHIP.IF.BUS._write_data(AddrSel, wb);
+ #else
+ #error "Abnoraml _WIZCHIP_IO_BUS_WIDTH_. Should be 8 or 16"
+ #endif
+#elif ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_) )
+ #if(_WIZCHIP_IO_BUS_WIDTH_ == 8)
+ WIZCHIP.IF.BUS._write_data(IDM_AR, (uint8_t)(AddrSel >> 8));
+ WIZCHIP.IF.BUS._write_data(WIZCHIP_OFFSET_INC(IDM_AR,1),(uint8_t)AddrSel);
+ WIZCHIP.IF.BUS._write_data(IDM_DR,(uint8_t)(wb>>8));
+ WIZCHIP.IF.BUS._write_data(WIZCHIP_OFFSET_INC(IDM_DR,1),(uint8_t)wb);
+ #elif(_WIZCHIP_IO_BUS_WIDTH_ == 16)
+ WIZCHIP.IF.BUS._write_data(IDM_AR, (uint16_t)AddrSel);
+ WIZCHIP.IF.BUS._write_data(IDM_DR, wb);
+ #else
+ #error "Abnoraml _WIZCHIP_IO_BUS_WIDTH_. Should be 8 or 16"
+ #endif
+#else
+ #error "Unknown _WIZCHIP_IO_MODE_ in W5300. !!!"
+#endif
+
+ WIZCHIP.CS._deselect();
+ WIZCHIP_CRITICAL_EXIT();
+}
+
+uint16_t WIZCHIP_READ(uint32_t AddrSel)
+{
+ uint16_t ret;
+
+ WIZCHIP_CRITICAL_ENTER();
+ WIZCHIP.CS._select();
+
+#if ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_DIR_) )
+ #if (_WIZCHIP_IO_BUS_WIDTH_ == 8)
+ ret = (((uint16_t)WIZCHIP.IF.BUS._read_data(AddrSel)) << 8) |
+ (((uint16_t)WIZCHIP.IF.BUS._read_data(WIZCHIP_OFFSET_INC(AddrSel,1))) & 0x00FF) ;
+ #elif(_WIZCHIP_IO_BUS_WIDTH_ == 16)
+ ret = WIZCHIP.IF.BUS._read_data(AddrSel);
+ #else
+ #error "Abnoraml _WIZCHIP_IO_BUS_WIDTH_. Should be 8 or 16"
+ #endif
+#elif ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_) )
+ #if(_WIZCHIP_IO_BUS_WIDTH_ == 8)
+ WIZCHIP.IF.BUS._write_data(IDM_AR, (uint8_t)(AddrSel >> 8));
+ WIZCHIP.IF.BUS._write_data(WIZCHIP_OFFSET_INC(IDM_AR,1),(uint8_t)AddrSel);
+ ret = (((uint16_t)WIZCHIP.IF.BUS._read_data(IDM_DR)) << 8) |
+ (((uint16_t)WIZCHIP.IF.BUS._read_data(WIZCHIP_OFFSET_INC(IDM_DR,1))) & 0x00FF);
+ #elif(_WIZCHIP_IO_BUS_WIDTH_ == 16)
+ WIZCHIP.IF.BUS._write_data(IDM_AR, (uint16_t)AddrSel);
+ ret = WIZCHIP.IF.BUS._read_data(IDM_DR);
+ #else
+ #error "Abnoraml _WIZCHIP_IO_BUS_WIDTH_. Should be 8 or 16"
+ #endif
+#else
+ #error "Unknown _WIZCHIP_IO_MODE_ in W5300. !!!"
+#endif
+
+ WIZCHIP.CS._deselect();
+ WIZCHIP_CRITICAL_EXIT();
+ return ret;
+}
+
+
+void setTMSR(uint8_t sn,uint8_t tmsr)
+{
+ uint16_t tmem;
+ tmem = WIZCHIP_READ(WIZCHIP_OFFSET_INC(TMS01R, (sn & 0xFE)));
+ if(sn & 0x01) tmem = (tmem & 0xFF00) | (((uint16_t)tmsr ) & 0x00FF) ;
+ else tmem = (tmem & 0x00FF) | (((uint16_t)tmsr) << 8) ;
+ WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(TMS01R, (sn & 0xFE)),tmem);
+}
+
+uint8_t getTMSR(uint8_t sn)
+{
+ if(sn & 0x01)
+ return (uint8_t)(WIZCHIP_READ(WIZCHIP_OFFSET_INC(TMS01R, (sn & 0xFE))) & 0x00FF);
+ return (uint8_t)(WIZCHIP_READ(WIZCHIP_OFFSET_INC(TMS01R, (sn & 0xFE))) >> 8);
+}
+
+void setRMSR(uint8_t sn,uint8_t rmsr)
+{
+ uint16_t rmem;
+ rmem = WIZCHIP_READ(WIZCHIP_OFFSET_INC(RMS01R, (sn & 0xFE)));
+ if(sn & 0x01) rmem = (rmem & 0xFF00) | (((uint16_t)rmsr ) & 0x00FF) ;
+ else rmem = (rmem & 0x00FF) | (((uint16_t)rmsr) << 8) ;
+ WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(RMS01R, (sn & 0xFE)),rmem);
+}
+
+uint8_t getRMSR(uint8_t sn)
+{
+ if(sn & 0x01)
+ return (uint8_t)(WIZCHIP_READ(WIZCHIP_OFFSET_INC(RMS01R, (sn & 0xFE))) & 0x00FF);
+ return (uint8_t)(WIZCHIP_READ(WIZCHIP_OFFSET_INC(RMS01R, (sn & 0xFE))) >> 8);
+}
+
+uint32_t getSn_TX_FSR(uint8_t sn)
+{
+ uint32_t free_tx_size=0;
+ uint32_t free_tx_size1=1;
+ while(1)
+ {
+ free_tx_size = (((uint32_t)WIZCHIP_READ(Sn_TX_FSR(sn))) << 16) |
+ (((uint32_t)WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn),2))) & 0x0000FFFF); // read
+ if(free_tx_size == free_tx_size1) break; // if first == sencond, Sn_TX_FSR value is valid.
+ free_tx_size1 = free_tx_size; // save second value into first
+ }
+ return free_tx_size;
+}
+
+uint32_t getSn_RX_RSR(uint8_t sn)
+{
+ uint32_t received_rx_size=0;
+ uint32_t received_rx_size1=1;
+ while(1)
+ {
+ received_rx_size = (((uint32_t)WIZCHIP_READ(Sn_RX_RSR(sn))) << 16) |
+ (((uint32_t)WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn),2))) & 0x0000FFFF);
+ if(received_rx_size == received_rx_size1) break;
+ received_rx_size1 = received_rx_size; // if first == sencond, Sn_RX_RSR value is valid.
+ } // save second value into first
+ return received_rx_size + (uint32_t)((sock_pack_info[sn] & 0x02) ? 1 : 0);
+}
+
+
+void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint32_t len)
+{
+ uint32_t i = 0;
+ if(len == 0) return;
+
+ for(i = 0; i < len ; i += 2)
+ setSn_TX_FIFOR(sn, (((uint16_t)wizdata[i]) << 8) | (((uint16_t)wizdata[i+1]) & 0x00FF))
+}
+
+void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint32_t len)
+{
+ uint16_t rd = 0;
+ uint32_t i = 0;
+
+ if(len == 0) return;
+
+ for(i = 0; i < len; i++)
+ {
+ if((i & 0x01)==0)
+ {
+ rd = getSn_RX_FIFOR(sn);
+ wizdata[i] = (uint8_t)(rd >> 8);
+ }
+ else wizdata[i] = (uint8_t)rd; // For checking the memory access violation
+ }
+ sock_remained_byte[sn] = (uint8_t)rd; // back up the remaind fifo byte.
+}
+
+void wiz_recv_ignore(uint8_t sn, uint32_t len)
+{
+ uint32_t i = 0;
+ for(i = 0; i < len ; i += 2) getSn_RX_FIFOR(sn);
+}
+
+
+#endif
diff --git a/Libraries/ioLibrary_Driver/Ethernet/W5300/w5300.h b/Libraries/ioLibrary_Driver/Ethernet/W5300/w5300.h
new file mode 100644
index 0000000..371699b
--- /dev/null
+++ b/Libraries/ioLibrary_Driver/Ethernet/W5300/w5300.h
@@ -0,0 +1,2327 @@
+#ifndef _W5300_H_
+#define _W5300_H_
+//*****************************************************************************
+//
+//! \file w5300.h
+//! \brief W5300 HAL Header File.
+//! \version 1.0.0
+//! \date 2015/05/01
+//! \par Revision history
+//! <2015/05/01> 1st Released for integrating with ioLibrary
+//! Download the latest version directly from GitHub. Please visit the our GitHub repository for ioLibrary.
+//! >> https://github.com/Wiznet/ioLibrary_Driver
+//! \author MidnightCow
+//! \copyright
+//!
+//! Copyright (c) 2015, WIZnet Co., LTD.
+//! All rights reserved.
+//!
+//! Redistribution and use in source and binary forms, with or without
+//! modification, are permitted provided that the following conditions
+//! are met:
+//!
+//! * Redistributions of source code must retain the above copyright
+//! notice, this list of conditions and the following disclaimer.
+//! * Redistributions in binary form must reproduce the above copyright
+//! notice, this list of conditions and the following disclaimer in the
+//! documentation and/or other materials provided with the distribution.
+//! * Neither the name of the nor the names of its
+//! contributors may be used to endorse or promote products derived
+//! from this software without specific prior written permission.
+//!
+//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+//! THE POSSIBILITY OF SUCH DAMAGE.
+//
+//*****************************************************************************
+
+#include
+#include "wizchip_conf.h"
+
+/// \cond DOXY_APPLY_CODE
+#if (_WIZCHIP_ == 5300)
+/// \endcond
+
+#define _WIZCHIP_SN_BASE_ (0x0200)
+#define _WIZCHIP_SN_SIZE_ (0x0040)
+
+
+#define WIZCHIP_CREG_BLOCK 0x00 ///< Common register block
+#define WIZCHIP_SREG_BLOCK(N) (_WIZCHIP_SN_BASE_+ _WIZCHIP_SN_SIZE_*N) ///< Socket N register block
+
+#define WIZCHIP_OFFSET_INC(ADDR, N) (ADDR + N) ///< Increase offset address
+
+#if (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_DIR_)
+ #define _W5300_IO_BASE_ _WIZCHIP_IO_BASE_
+#elif (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_)
+ #define IDM_AR ((_WIZCHIP_IO_BASE_ + 0x0002)) ///< Indirect mode address register
+ #define IDM_DR ((_WIZCHIP_IO_BASE_ + 0x0004)) ///< Indirect mode data register
+ #define _W5300_IO_BASE_ 0x0000
+#elif (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_)
+ #error "Unkonw _WIZCHIP_IO_MODE_"
+#endif
+
+///////////////////////////////////////
+// Definition For Legacy Chip Driver //
+///////////////////////////////////////
+#define IINCHIP_READ(ADDR) WIZCHIP_READ(ADDR) ///< The defined for legacy chip driver
+#define IINCHIP_WRITE(ADDR,VAL) WIZCHIP_WRITE(ADDR,VAL) ///< The defined for legacy chip driver
+//#define IINCHIP_READ_BUF(ADDR,BUF,LEN) WIZCHIP_READ_BUF(ADDR,BUF,LEN) ///< The defined for legacy chip driver
+//#define IINCHIP_WRITE_BUF(ADDR,BUF,LEN) WIZCHIP_WRITE(ADDR,BUF,LEN) ///< The defined for legacy chip driver
+
+//-------------------------- defgroup ---------------------------------
+/**
+ * @defgroup W5300 W5300
+ *
+ * @brief WHIZCHIP register defines and I/O functions of @b W5300.
+ *
+ * - @ref WIZCHIP_register_W5300 : @ref Common_register_group_W5300 and @ref Socket_register_group_W5300
+ * - @ref WIZCHIP_IO_Functions_W5300 : @ref Basic_IO_function_W5300, @ref Common_register_access_function_W5300 and @ref Socket_register_access_function_W5300
+ */
+
+
+/**
+ * @defgroup WIZCHIP_register_W5300 WIZCHIP register
+ * @ingroup W5300
+ *
+ * @brief WHIZCHIP register defines register group of @b W5300.
+ *
+ * - @ref Common_register_group_W5300 : Common register group
+ * - @ref Socket_register_group_W5300 : \c SOCKET n register group
+ */
+
+
+/**
+ * @defgroup WIZCHIP_IO_Functions_W5300 WIZCHIP I/O functions
+ * @ingroup W5300
+ *
+ * @brief This supports the basic I/O functions for @ref WIZCHIP_register_W5300.
+ *
+ * - Basic I/O function \n
+ * WIZCHIP_READ(), WIZCHIP_WRITE() \n\n
+ *
+ * - @ref Common_register_group_W5300 access functions \n
+ * -# @b Mode \n
+ * getMR(), setMR()
+ * -# @b Interrupt \n
+ * getIR(), setIR(), getIMR(), setIMR(), getSIR(), setSIR(), getSIMR(), setSIMR()
+ * -# Network Information \n
+ * getSHAR(), setSHAR(), getGAR(), setGAR(), getSUBR(), setSUBR(), getSIPR(), setSIPR()
+ * -# @b Retransmission \n
+ * getRCR(), setRCR(), getRTR(), setRTR()
+ * -# @b PPPoE \n
+ * getPTIMER(), setPTIMER(), getPMAGIC(), getPMAGIC(), getPSID(), setPSID(), getPHAR(), setPHAR(), getPMRU(), setPMRU()
+ * -# ICMP packet \n
+ * getUIPR(), getUPORTR()
+ * -# @b Socket Memory \n
+ * getMTYPER(), setMTYPER() \n
+ * getTMS01R(), getTMS23R(), getTMS45R(), getTMS67R(), setTMS01R(), setTMS23R(), setTMS45R(), setTMS67R() \n
+ * getRMS01R(), getRMS23R(), getRMS45R(), getRMS67R(), setRMS01R(), setRMS23R(), setRMS45R(), setRMS67R() \n
+ * -# @b etc. \n
+ * getPn_BRDYR(), setPn_BRDYR(), getPn_BDPTHR(), setPn_BDPTHR(), getIDR() \n\n
+ *
+ * - \ref Socket_register_group_W5300 access functions \n
+ * -# SOCKET control \n
+ * getSn_MR(), setSn_MR(), getSn_CR(), setSn_CR(), getSn_IMR(), setSn_IMR(), getSn_IR(), setSn_IR()
+ * -# SOCKET information \n
+ * getSn_SR(), getSn_DHAR(), setSn_DHAR(), getSn_PORT(), setSn_PORT(), getSn_DIPR(), setSn_DIPR(), getSn_DPORT(), setSn_DPORT()
+ * getSn_MSSR(), setSn_MSSR()
+ * -# SOCKET communication \n
+ * getSn_RXBUF_SIZE(), setSn_RXBUF_SIZE(), getSn_TXBUF_SIZE(), setSn_TXBUF_SIZE() \n
+ * getSn_TX_RD(), getSn_TX_WR(), setSn_TX_WR() \n
+ * getSn_RX_RD(), setSn_RX_RD(), getSn_RX_WR() \n
+ * getSn_TX_FSR(), getSn_RX_RSR(), getSn_KPALVTR(), setSn_KPALVTR()
+ * -# IP header field \n
+ * getSn_FRAG(), setSn_FRAG(), getSn_TOS(), setSn_TOS() \n
+ * getSn_TTL(), setSn_TTL()
+ */
+
+
+/**
+ * @defgroup Common_register_group_W5300 Common register
+ * @ingroup WIZCHIP_register_W5300
+ *
+ * @brief Common register group\n
+ * It set the basic for the networking\n
+ * It set the configuration such as interrupt, network information, ICMP, etc.
+ * @details
+ * @sa MR : Mode register.
+ * @sa GAR, SUBR, SHAR, SIPR : Network Configuration
+ * @sa IR, _IMR_ : Interrupt.
+ * @sa MTYPER, TMS01R,TMS23R, TMS45R, TMS67R,RMS01R,RMS23R, RMS45R, RMS67R : Socket TX/RX memory
+ * @sa _RTR_, _RCR_ : Data retransmission.
+ * @sa PTIMER, PMAGIC, PSID, PDHAR : PPPoE.
+ * @sa UIPR, UPORTR, FMTUR : ICMP message.
+ * @sa Pn_BRDYR, Pn_BDPTHR, IDR : etc.
+ */
+
+
+/**
+ * @defgroup Socket_register_group_W5300 Socket register
+ * @ingroup WIZCHIP_register_W5300
+ *
+ * @brief Socket register group.\n
+ * Socket register configures and control SOCKETn which is necessary to data communication.
+ * @details
+ * @sa Sn_MR, Sn_CR, Sn_IR, Sn_IMR : SOCKETn Control
+ * @sa Sn_SR, Sn_PORT, Sn_DHAR, Sn_DIPR, Sn_DPORT : SOCKETn Information
+ * @sa Sn_MSSR, Sn_TOS, Sn_TTL, Sn_KPALVTR, Sn_FRAG : Internet protocol.
+ * @sa Sn_TX_WRSR, Sn_TX_FSR, Sn_TX_RD, Sn_TX_WR, Sn_RX_RSR, Sn_RX_RD, Sn_RX_WR, Sn_TX_FIFOR, Sn_RX_FIFOR : Data communication
+ */
+
+
+ /**
+ * @defgroup Basic_IO_function_W5300 Basic I/O function
+ * @ingroup WIZCHIP_IO_Functions_W5300
+ * @brief These are basic input/output functions to read values from register or write values to register.
+ */
+
+/**
+ * @defgroup Common_register_access_function_W5300 Common register access functions
+ * @ingroup WIZCHIP_IO_Functions_W5300
+ * @brief These are functions to access common registers.
+ */
+
+/**
+ * @defgroup Socket_register_access_function_W5300 Socket register access functions
+ * @ingroup WIZCHIP_IO_Functions_W5300
+ * @brief These are functions to access socket registers.
+ */
+
+//------------------------------- defgroup end --------------------------------------------
+
+//----------------------------- W5300 Common Registers -----------------------------
+/**
+ * @ingroup Common_register_group_W5300
+ * @brief Mode Register address(R/W)\n
+ * @ref MR is used for S/W reset, ping block mode, PPPoE mode and etc.
+ * @details Each bit of @ref MR defined as follows.
+ *
+ *
15
14
13
12
11
10
9
8
+ *
DBW
MPF
WDF
RDF
Reserved
FS
+ *
7
6
5
4
3
2
1
0
+ *
RST
Reserved
WOL
PB
PPPoE
Reserved
FARP
Reserved
+ *
+ * - \ref MR_DBW : Data bus width (0 : 8 Bit, 1 : 16 Bit), Read Only
+ * - \ref MR_MPF : Received a Pause Frame from MAC layer (0 : Normal Frame, 1 : Pause Frame), Read Only
+ * - \ref MR_WDF : Write Data Fetch time (When CS signal is low, W5300 Fetch a written data by Host after PLL_CLK * MR_WDF)
+ * - \ref MR_RDH : Read Data Hold time (0 : No use data hold time, 1 : Use data hold time, 2 PLL_CLK)
+ * - \ref MR_FS : FIFO Swap (0 : Disable Swap, 1 : Enable Swap)
+ * - \ref MR_RST : Reset
+ * - \ref MR_WOL : Wake on LAN
+ * - \ref MR_PB : Ping block
+ * - \ref MR_PPPOE : PPPoE mode
+ * - \ref MR_FARP : Force ARP mode
+ */
+#define MR (_WIZCHIP_IO_BASE_)
+
+/**
+ * @ingroup Common_register_group_W5300
+ * @brief Interrupt Register(R/W)
+ * @details \ref IR indicates the interrupt status. Each bit of \ref IR will be still until the bit will be written to by the host.
+ * If \ref IR is not equal to 0x0000 INTn PIN is asserted to low until it is 0x0000\n\n
+ * Each bit of \ref IR defined as follows.
+ *
+ *
15
14
13
12
11
10
9
8
+ *
IPCF
DPUR
PPPT
FMTU
Reserved
Reserved
Reserved
Reserved
+ *
7
6
5
4
3
2
1
0
+ *
S7_INT
S6_INT
S5_INT
S4_INT
S3_INT
S2_INT
S1_INT
S0_INT
+ *
+ * - \ref IR_IPCF : IP conflict
+ * - \ref IR_DPUR : Destination Port Unreachable
+ * - \ref IR_PPPT : PPPoE Termination
+ * - \ref IR_FMTU : Fragmented MTU
+ * - \ref IR_SnINT(n) : Interrupted from SOCKETn
+ *
+ * @note : In W5300, IR is operated same as IR and SIR in other WIZCHIP(5100,5200,W5500)
+ */
+#define IR (_W5300_IO_BASE_ + 0x02)
+
+/**
+ * @ingroup Common_register_group_W5300
+ * @brief Socket Interrupt Mask Register(R/W)
+ * @details Each bit of \ref _IMR_ corresponds to each bit of \ref IR.
+ * When a bit of _IMR_ is and the corresponding bit of \ref IR is Interrupt will be issued.
+ * In other words, if a bit of _IMR_, an interrupt will be not issued even if the corresponding bit of \ref IR is set
+ * @note : In W5300, _IMR_ is operated same as _IMR_ and SIMR in other WIZCHIP(5100,5200,W5500)
+ */
+#define _IMR_ (_W5300_IO_BASE_ + 0x04)
+
+
+//#define ICFGR (_W5300_IO_BASE_ + 0x06)
+//#define INTLEVEL ICFGR
+
+/**
+ * @ingroup Common_register_group_W5300
+ * @brief Source MAC Register address(R/W)
+ * @details @ref SHAR configures the source hardware address.
+ */
+#define SHAR (_W5300_IO_BASE_ + 0x08)
+
+
+/**
+ * @ingroup Common_register_group_W5300
+ * @brief Gateway IP Register address(R/W)
+ * @details @ref GAR configures the default gateway address.
+ */
+ #define GAR (_W5300_IO_BASE_ + 0x10)
+
+/**
+ * @ingroup Common_register_group_W5300
+ * @brief Subnet mask Register address(R/W)
+ * @details @ref SUBR configures the subnet mask address.
+ */
+#define SUBR (_W5300_IO_BASE_ + 0x14)
+
+/**
+ * @ingroup Common_register_group_W5300
+ * @brief Source IP Register address(R/W)
+ * @details @ref SIPR configures the source IP address.
+ */
+#define SIPR (_W5300_IO_BASE_ + 0x18)
+
+/**
+ * @ingroup Common_register_group_W5300
+ * @brief Timeout register address( 1 is 100us )(R/W)
+ * @details @ref _RTR_ configures the retransmission timeout period. The unit of timeout period is 100us and the default of @ref _RTR_ is x07D0.
+ * And so the default timeout period is 200ms(100us X 2000). During the time configured by @ref _RTR_, W5300 waits for the peer response
+ * to the packet that is transmitted by \ref Sn_CR (CONNECT, DISCON, CLOSE, SEND, SEND_MAC, SEND_KEEP command).
+ * If the peer does not respond within the @ref _RTR_ time, W5300 retransmits the packet or issues timeout.
+ */
+ #define _RTR_ (_W5300_IO_BASE_ + 0x1C)
+
+/**
+ * @ingroup Common_register_group_W5300
+ * @brief Retry count register(R/W)
+ * @details @ref _RCR_ configures the number of time of retransmission.
+ * When retransmission occurs as many as ref _RCR_+1 Timeout interrupt is issued (@ref Sn_IR_TIMEOUT = '1').
+ */
+#define _RCR_ (_W5300_IO_BASE_ + 0x1E)
+
+/**
+ * @ingroup Common_register_group_W5300
+ * @brief TX memory size of \c SOCKET 0 & 1
+ * @details TMS01R configures the TX buffer block size of \c SOCKET 0 & 1. The default value is configured with 8KB and can be configure from 0 to 64KB with unit 1KB.
+ * But the sum of all SOCKET TX buffer size should be multiple of 8 and the sum of all SOCKET TX and RX memory size can't exceed 128KB.
+ * When exceeded nor multiple of 8, the data transmittion is invalid.
+ */
+#define TMS01R (_W5300_IO_BASE_ + 0x20)
+
+/**
+ * @ingroup Common_register_group_W5300
+ * @brief TX memory size of \c SOCKET 2 & 3
+ * @details refer to \ref TMS01R
+ */
+#define TMS23R (TMS01R + 2)
+
+/**
+ * @ingroup Common_register_group_W5300
+ * @brief TX memory size of \c SOCKET 4 & 5
+ * @details refer to \ref TMS01R
+ */
+#define TMS45R (TMS01R + 4)
+
+/**
+ * @ingroup Common_register_group_W5300
+ * @brief TX memory size of \c SOCKET 6 & 7
+ * @details refer to \ref TMS01R
+ */
+#define TMS67R (TMS01R + 6)
+
+/**
+ * @ingroup Common_register_group_W5300
+ * @brief TX memory size of \c SOCKET 0.
+ * @details refer to \ref TMS01R
+ */
+#define TMSR0 TMS01R
+
+/**
+ * @ingroup Common_register_group_W5300
+ * @brief TX memory size of \c SOCKET 1.
+ * @details refer to \ref TMS01R
+ */
+#define TMSR1 (TMSR0 + 1)
+
+/**
+ * @ingroup Common_register_group_W5300
+ * @brief TX memory size of \c SOCKET 2.
+ * @details refer to \ref TMS01R
+ */
+#define TMSR2 (TMSR0 + 2)
+
+/**
+ * @ingroup Common_register_group_W5300
+ * @brief TX memory size of \c SOCKET 3.
+ * @details refer to \ref TMS01R
+ */
+#define TMSR3 (TMSR0 + 3)
+
+/**
+ * @ingroup Common_register_group_W5300
+ * @brief TX memory size of \c SOCKET 4.
+ * @details refer to \ref TMS01R
+ */
+#define TMSR4 (TMSR0 + 4)
+
+/**
+ * @ingroup Common_register_group_W5300
+ * @brief TX memory size of \c SOCKET 5.
+ * @details refer to \ref TMS01R
+ */
+#define TMSR5 (TMSR0 + 5)
+
+/**
+ * @ingroup Common_register_group_W5300
+ * @brief TX memory size of \c SOCKET 6.
+ * @details refer to \ref TMS01R
+ */
+#define TMSR6 (TMSR0 + 6)
+
+/**
+ * @ingroup Common_register_group_W5300
+ * @brief TX memory size of \c SOCKET 7.
+ * @details refer to \ref TMS01R
+ */
+#define TMSR7 (TMSR0 + 7)
+
+
+/**
+ * @ingroup Common_register_group_W5300
+ * @brief RX memory size of \c SOCKET 0 & 1
+ * @details RMS01R configures the RX buffer block size of \c SOCKET 0 & 1. The default value is configured with 8KB and can be configure from 0 to 64KB with unit 1KB.
+ * But the sum of all SOCKET RX buffer size should be multiple of 8 and the sum of all SOCKET RX and TX memory size can't exceed 128KB.
+ * When exceeded nor multiple of 8, the data reception is invalid.
+ */
+#define RMS01R (_W5300_IO_BASE_ + 0x28)
+
+/**
+ * @ingroup Common_register_group_W5300
+ * @brief RX memory size of \c SOCKET 2 & 3
+ * @details Refer to \ref RMS01R
+ */
+#define RMS23R (RMS01R + 2)
+
+/**
+ * @ingroup Common_register_group_W5300
+ * @brief RX memory size of \c SOCKET 4 & 5
+ * @details Refer to \ref RMS01R
+ */
+#define RMS45R (RMS01R + 4)
+
+/**
+ * @ingroup Common_register_group_W5300
+ * @brief RX memory size of \c SOCKET 6 & 7
+ * @details Refer to \ref RMS01R
+ */
+#define RMS67R (RMS01R + 6)
+
+/**
+ * @ingroup Common_register_group_W5300
+ * @brief RX memory size of \c SOCKET 0.
+ * @details refer to \ref RMS01R
+ */
+#define RMSR0 RMS01R
+
+/**
+ * @ingroup Common_register_group_W5300
+ * @brief RX memory size of \c SOCKET 1.
+ * @details refer to \ref RMS01R
+ */
+#define RMSR1 (RMSR0 + 1)
+
+/**
+ * @ingroup Common_register_group_5300
+ * @brief RX memory size of \c SOCKET 2.
+ * @details refer to \ref RMS01R
+ */
+#define RMSR2 (RMSR0 + 2)
+
+/**
+ * @ingroup Common_register_group_W5300
+ * @brief RX memory size of \c SOCKET 3.
+ * @details refer to \ref RMS01R
+ */
+#define RMSR3 (RMSR0 + 3)
+
+/**
+ * @ingroup Common_register_group_W5300
+ * @brief RX memory size of \c SOCKET 4.
+ * @details refer to \ref RMS01R
+ */
+#define RMSR4 (RMSR0 + 4)
+
+/**
+ * @ingroup Common_register_group_W5300
+ * @brief RX memory size of \c SOCKET 5.
+ * @details refer to \ref RMS01R
+ */
+#define RMSR5 (RMSR0 + 5)
+
+/**
+ * @ingroup Common_register_group_W5300
+ * @brief RX memory size of \c SOCKET 6.
+ * @details refer to \ref RMS01R
+ */
+#define RMSR6 (RMSR0 + 6)
+
+/**
+ * @ingroup Common_register_group_W5300
+ * @brief RX memory size of \c SOCKET 7.
+ * @details refer to \ref RMS01R
+ */
+#define RMSR7 (RMSR0 + 7)
+
+
+
+/**
+ * @ingroup Common_register_group_W5300
+ * @brief Memory Type Register
+ * @details W5300’s 128Kbytes data memory (Internal TX/RX memory) is composed of 16 memory blocks
+ * of 8Kbytes. MTYPER configures type of each 8KB memory block in order to select RX or TX memory.
+ * The type of 8KB memory block corresponds to each bit of MTYPER. When the bit is ‘1’, it is used as TX
+ * memory, and the bit is ‘0’, it is used as RX memory. MTYPER is configured as TX memory type
+ * from the lower bit. The rest of the bits not configured as TX memory, should be set as ‘0’.
+ */
+#define MTYPER (_W5300_IO_BASE_ + 0x30)
+
+/**
+ * @ingroup Common_register_group_W5300
+ * @brief PPPoE Authentication Type register
+ * @details It notifies authentication method negotiated with PPPoE server.
+ * W5300 supports 2 types of authentication methods.
+ * - PAP : 0xC023
+ * - CHAP : 0xC223
+ */
+#define PATR (_W5300_IO_BASE_ + 0x32)
+
+//#define PPPALGOR (_W5300_IO_BASE_ + 0x34)
+
+/**
+ * @ingroup Common_register_group_W5300
+ * @brief PPP Link Control Protocol Request Timer Register
+ * @details It configures transmitting timer of link control protocol (LCP) echo request. Value 1 is about 25ms.
+ */
+#define PTIMER (_W5300_IO_BASE_ + 0x36)
+
+/**
+ * @ingroup Common_register_group_W5300
+ * @brief PPP LCP magic number register
+ * @details It configures byte value to be used for 4bytes “Magic Number” during LCP negotiation with PPPoE server.
+ */
+#define PMAGICR (_W5300_IO_BASE_ + 0x38)
+
+//#define PSTATER (_W5300_IO_BASE_ + 0x3A)
+
+/**
+ * @ingroup Common_register_group_W5300
+ * @brief PPPoE session ID register
+ * @details It notifies PPP session ID to be used for communication with PPPoE server (acquired by PPPoE-process of W5300).
+ */
+#define PSIDR (_W5300_IO_BASE_ + 0x3C)
+
+/**
+ * @ingroup Common_register_group_W5300
+ * @brief PPPoE destination hardware address register
+ * @details It notifies hardware address of PPPoE server (acquired by PPPoE-process of W5300).
+ */
+#define PDHAR (_W5300_IO_BASE_ + 0x40)
+
+/**
+ * @ingroup Common_register_group_W5300
+ * @brief Unreachable IP address register
+ * @details When trying to transmit UDP data to destination port number which is not open,
+ * W5300 can receive ICMP (Destination port unreachable) packet. \n
+ * In this case, \ref IR_DPUR bit of \ref IR becomes '1'.
+ * And destination IP address and unreachable port number of ICMP packet can be acquired through UIPR and \ref UPORTR.
+ */
+#define UIPR (_W5300_IO_BASE_ + 0x48)
+
+/**
+ * @ingroup Common_register_group_W5300
+ * @brief Unreachable port number register
+ * @details Refer to \ref UIPR.
+ */
+#define UPORTR (_W5300_IO_BASE_ + 0x4C)
+
+/**
+ * @ingroup Common_register_group_W5300
+ * @brief Fragment MTU register
+ * @details When communicating with the peer having a different MTU, W5300 can receive an ICMP(Fragment MTU) packet.
+ * At this case, IR(FMTU) becomes ‘1’ and destination IP address and fragment MTU value of ICMP packet can be acquired through UIPR and FMTUR.
+ * In order to keep communicating with the peer having Fragment MTU, set the FMTUR first in Sn_MSSR of the SOCKETn, and try the next communication.
+ */
+#define FMTUR (_W5300_IO_BASE_ + 0x4E)
+
+//#define Sn_RTCR(n) (_W5300_IO_BASE_ + 0x50 + n*2)
+
+/**
+ * @ingroup Common_register_group_W5300
+ * @brief PIN 'BRDYn' configure register
+ * @details It configures the PIN "BRDYn" which is monitoring TX/RX memory status of the specified SOCKET.
+ * If the free buffer size of TX memory is same or bigger than the buffer depth of \ref Pn_BDPTHR,
+ * or received buffer size of RX memory is same or bigger than the \ref Pn_BDPTHR,
+ * PIN "BRDYn" is signaled.
+ *
+ *
15
14
13
12
11
10
9
8
+ *
Reserved, Read as 0
+ *
7
6
5
4
3
2
1
0
+ *
PEN
MT
PPL
Reserved
SN
+ *
+ *
+ * - \ref Pn_PEN Enable PIN 'BRDYn' (0 : Disable, 1 : Enable)
+ * - \ref Pn_MT Monitoring Memory type (0 : RX memory, 1 : TX Memory)
+ * - \ref Pn_PPL PIN Polarity bit of Pn_BRDYR. (0 : Low sensitive, 1 : High sensitive)
+ * - \ref Pn_SN(n) Monitoring SOCKET number of Pn_BRDYR
+ */
+#define Pn_BRDYR(n) (_W5300_IO_BASE_ + 0x60 + n*4)
+
+/**
+ * @ingroup Common_register_group_W5300
+ * @brief PIN 'BRDYn' buffer depth Register
+ * @details It configures buffer depth of PIN "BRDYn".
+ * When monitoring TX memory and \ref Sn_TX_FSR is same or bigger than Pn_BDPTHR, the PIN "BRDYn" is signaled.
+ * When monitoring RX memory and if \ref Sn_RX_RSR is same or bigger than Pn_BDPTHR, PIN "BRDYn" is signaled.
+ * The value for Pn_BDPTHR can't exceed TX/RX memory size allocated by TMSR or RMSR such like as \ref TMS01R or \ref RMS01R.
+ */
+#define Pn_BDPTHR(n) (_W5300_IO_BASE_ + 0x60 + n*4 + 2)
+
+/**
+ * @ingroup Common_register_group_W5300
+ * @brief W5300 identification register.
+ * @details Read Only. 0x5300.
+ */
+#define IDR (_W5300_IO_BASE_ + 0xFE)
+#define VERSIONR IDR
+
+
+//----------------------------- W5300 SOCKET Registers -----------------------------
+
+/**
+ * @ingroup Socket_register_group_W5300
+ * @brief Socket Mode register(R/W)
+ * @details @ref Sn_MR configures the option or protocol type of Socket n.\n\n
+ * Each bit of @ref Sn_MR defined as the following.
+ *
+ *
15
14
13
12
11
10
9
8
+ *
Reserved. Read as 0
ALIGN
+ *
7
6
5
4
3
2
1
0
+ *
MULTI
MF
ND/IGMPv
Reserved
PROTOCOL[3:0]
+ *
+ * - @ref Sn_MR_ALIGN : Alignment bit of Sn_MR, Only valid in \ref Sn_MR_TCP. (C0 : Include TCP PACK_INFO, 1 : Not include TCP PACK_INFO)
+ * - @ref Sn_MR_MULTI : Support UDP Multicasting
+ * - @ref Sn_MR_MF : Enable MAC Filter (0 : Disable, 1 - Enable), When enabled, W5300 can receive only both own and broadcast packet.
+ * - @ref Sn_MR_ND : No Delayed Ack(TCP) flag
+ * - @ref Sn_MR_IGMPv : IGMP version used in UDP mulitcasting. (0 : Version 2, 1 : Version 2)
+ * - PROTOCOL[3:0]
+ *
+ *
Protocol[3]
Protocol[2]
Protocol[1]
Protocol[0]
@b Meaning
+ *
0
0
0
0
Closed
+ *
0
0
0
1
TCP
+ *
0
0
1
0
UDP
+ *
0
0
1
1
IPCRAW
+ *
0
1
0
0
MACRAW
+ *
0
1
0
1
PPPoE
+ *
+ *
+ * - @ref Sn_MR_PPPoE : PPPoE
+ * - @ref Sn_MR_MACRAW : MAC LAYER RAW SOCK
+ * - @ref Sn_MR_IPRAW : IP LAYER RAW SOCK
+ * - @ref Sn_MR_UDP : UDP
+ * - @ref Sn_MR_TCP : TCP
+ * - @ref Sn_MR_CLOSE : Unused socket
+ * @note MACRAW mode should be only used in Socket 0.
+ */
+#define Sn_MR(n) (_W5300_IO_BASE_ + WIZCHIP_SREG_BLOCK(n) + 0x00)
+
+/**
+ * @ingroup Socket_register_group_W5300
+ * @brief Socket command register(R/W)
+ * @details This is used to set the command for Socket n such as OPEN, CLOSE, CONNECT, LISTEN, SEND, and RECEIVE.\n
+ * After W5500 accepts the command, the @ref Sn_CR register is automatically cleared to 0x00.
+ * Even though @ref Sn_CR is cleared to 0x00, the command is still being processed.\n
+ * To check whether the command is completed or not, please check the @ref Sn_IR or @ref Sn_SR.
+ * - @ref Sn_CR_OPEN : Initialize or open socket.
+ * - @ref Sn_CR_LISTEN : Wait connection request in TCP mode(Server mode)
+ * - @ref Sn_CR_CONNECT : Send connection request in TCP mode(Client mode)
+ * - @ref Sn_CR_DISCON : Send closing request in TCP mode.
+ * - @ref Sn_CR_CLOSE : Close socket.
+ * - @ref Sn_CR_SEND : Update TX buffer pointer and send data.
+ * - @ref Sn_CR_SEND_MAC : Send data with MAC address, so without ARP process.
+ * - @ref Sn_CR_SEND_KEEP : Send keep alive message.
+ * - @ref Sn_CR_RECV : Update RX buffer pointer and receive data.
+ * - @ref Sn_CR_PCON : PPPoE connection begins by transmitting PPPoE discovery packet.
+ * - @ref Sn_CR_PDISCON : Closes PPPoE connection.
+ * - @ref Sn_CR_PCR : In each phase, it transmits REQ message.
+ * - @ref Sn_CR_PCN : In each phase, it transmits NAK message.
+ * - @ref Sn_CR_PCJ : In each phase, it transmits REJECT message.
+ */
+#define Sn_CR(n) (_W5300_IO_BASE_ + WIZCHIP_SREG_BLOCK(n) + 0x02)
+
+/**
+ * @ingroup Socket_register_group_W5300
+ * @brief socket interrupt mask register(R)
+ * @details @ref Sn_IMR masks the interrupt of Socket n.
+ * Each bit corresponds to each bit of @ref Sn_IR. When a Socket n Interrupt is occurred and the corresponding bit of @ref Sn_IMR is
+ * the corresponding bit of @ref Sn_IR becomes When both the corresponding bit of @ref Sn_IMR and @ref Sn_IR are and the n-th bit of @ref IR is
+ * Host is interrupted by asserted INTn PIN to low.
+ */
+#define Sn_IMR(n) (_W5300_IO_BASE_ + WIZCHIP_SREG_BLOCK(n) + 0x04)
+
+/**
+ * @ingroup Socket_register_group_W5300
+ * @brief Socket interrupt register(R)
+ * @details @ref Sn_IR indicates the status of Socket Interrupt such as establishment, termination, receiving data, timeout).\n
+ * When an interrupt occurs and the corresponding bit of @ref Sn_IMR is the corresponding bit of @ref Sn_IR becomes \n
+ * In order to clear the @ref Sn_IR bit, the host should write the bit to \n
+ *
+ *
15
14
13
12
11
10
9
8
+ *
Reserved. Read as 0
+ *
7
6
5
4
3
2
1
0
+ *
PRECV
PFAIL
PNEXT
SENDOK
TIMEOUT
RECV
DISCON
CON
+ *
+ * - \ref Sn_IR_PRECV : PPP receive
+ * - \ref Sn_IR_PFAIL : PPP fail
+ * - \ref Sn_IR_PNEXT : PPP next phase
+ * - \ref Sn_IR_SENDOK : SENDOK
+ * - \ref Sn_IR_TIMEOUT : TIMEOUT
+ * - \ref Sn_IR_RECV : RECV
+ * - \ref Sn_IR_DISCON : DISCON
+ * - \ref Sn_IR_CON : CON
+ */
+#define Sn_IR(n) (_W5300_IO_BASE_ + WIZCHIP_SREG_BLOCK(n) + 0x06)
+
+/**
+ * @ingroup Socket_register_group_W5300
+ * @brief Socket status register(R)
+ * @details @ref Sn_SSR indicates the status of Socket n.\n
+ * The status of Socket n is changed by @ref Sn_CR or some special control packet as SYN, FIN packet in TCP.
+ * @par Normal status
+ * - @ref SOCK_CLOSED : Closed
+ * - @ref SOCK_INIT : Initiate state
+ * - @ref SOCK_LISTEN : Listen state
+ * - @ref SOCK_ESTABLISHED : Success to connect
+ * - @ref SOCK_CLOSE_WAIT : Closing state
+ * - @ref SOCK_UDP : UDP socket
+ * - @ref SOCK_IPRAW : IPRAW socket
+ * - @ref SOCK_MACRAW : MAC raw mode socket
+ * - @ref SOCK_PPPoE : PPPoE mode Socket
+ *@par Temporary status during changing the status of Socket n.
+ * - @ref SOCK_SYNSENT : This indicates Socket n sent the connect-request packet (SYN packet) to a peer.
+ * - @ref SOCK_SYNRECV : It indicates Socket n successfully received the connect-request packet (SYN packet) from a peer.
+ * - @ref SOCK_FIN_WAIT : Connection state
+ * - @ref SOCK_CLOSING : Closing state
+ * - @ref SOCK_TIME_WAIT : Closing state
+ * - @ref SOCK_LAST_ACK : Closing state
+ * - @ref SOCK_ARP : ARP request state
+ */
+#define Sn_SSR(n) (_W5300_IO_BASE_ + WIZCHIP_SREG_BLOCK(n) + 0x08)
+#define Sn_SR(n) Sn_SSR(n) ///< For Compatible ioLibrary. Refer to @ref Sn_SSR(n)
+
+/**
+ * @ingroup Socket_register_group_W5300
+ * @brief source port register(R/W)
+ * @details @ref Sn_PORTR configures the source port number of Socket n.
+ * It is valid when Socket n is used in TCP/UPD mode. It should be set before OPEN command is ordered.
+ */
+#define Sn_PORTR(n) (_W5300_IO_BASE_ + WIZCHIP_SREG_BLOCK(n) + 0x0A)
+#define Sn_PORT(n) Sn_PORTR(n) ///< For compatible ioLibrary. Refer to @ref Sn_PORTR(n).
+
+/**
+ * @ingroup Socket_register_group_W5300
+ * @brief Peer MAC register address(R/W)
+ * @details @ref Sn_DHAR configures the destination hardware address of Socket n when using SEND_MAC command in UDP mode or
+ * it indicates that it is acquired in ARP-process by CONNECT/SEND command.
+ */
+#define Sn_DHAR(n) (_W5300_IO_BASE_ + WIZCHIP_SREG_BLOCK(n) + 0x0C)
+
+/**
+ * @ingroup Socket_register_group_W5300
+ * @brief Peer port register address(R/W)
+ * @details @ref Sn_DPORTR configures or indicates the destination port number of Socket n. It is valid when Socket n is used in TCP/UDP mode.
+ * In TCP clientmode, it configures the listen port number of TCP serverbefore CONNECT command.
+ * In TCP Servermode, it indicates the port number of TCP client after successfully establishing connection.
+ * In UDP mode, it configures the port number of peer to be transmitted the UDP packet by SEND/SEND_MAC command.
+ */
+#define Sn_DPORTR(n) (_W5300_IO_BASE_ + WIZCHIP_SREG_BLOCK(n) + 0x12)
+#define Sn_DPORT(n) Sn_DPORTR(n) ///< For compatible ioLibrary. Refer to \ref Sn_DPORTR.
+
+
+/**
+ * @ingroup Socket_register_group_W5300
+ * @brief Peer IP register address(R/W)
+ * @details @ref Sn_DIPR configures or indicates the destination IP address of Socket n. It is valid when Socket n is used in TCP/UDP mode.
+ * In TCP client mode, it configures an IP address of TCP serverbefore CONNECT command.
+ * In TCP server mode, it indicates an IP address of TCP clientafter successfully establishing connection.
+ * In UDP mode, it configures an IP address of peer to be received the UDP packet by SEND or SEND_MAC command.
+ */
+ #define Sn_DIPR(n) (_W5300_IO_BASE_ + WIZCHIP_SREG_BLOCK(n) + 0x14)
+
+/**
+ * @ingroup Socket_register_group_W5300
+ * @brief Maximum Segment Size(Sn_MSSR0) register address(R/W)
+ * @details @ref Sn_MSSR configures or indicates the MTU(Maximum Transfer Unit) of Socket n.
+ */
+#define Sn_MSSR(n) (_W5300_IO_BASE_ + WIZCHIP_SREG_BLOCK(n) + 0x18)
+
+/**
+ * @ingroup Socket_register_group_W5300
+ * @brief Keep Alive Timer register(R/W)
+ * @details @ref Sn_KPALVTR configures the transmitting timer of KEEP ALIVE(KA)packet of SOCKETn. It is valid only in TCP mode,
+ * and ignored in other modes. The time unit is 5s.
+ * KA packet is transmittable after @ref Sn_SR is changed to SOCK_ESTABLISHED and after the data is transmitted or received to/from a peer at least once.
+ * In case of '@ref Sn_KPALVTR > 0', W5500 automatically transmits KA packet after time-period for checking the TCP connection (Auto-keepalive-process).
+ * In case of '@ref Sn_KPALVTR = 0', Auto-keep-alive-process will not operate,
+ * and KA packet can be transmitted by SEND_KEEP command by the host (Manual-keep-alive-process).
+ * Manual-keep-alive-process is ignored in case of '@ref Sn_KPALVTR > 0'.
+ */
+#define Sn_KPALVTR(n) (_W5300_IO_BASE_ + WIZCHIP_SREG_BLOCK(n) + 0x1A)
+
+/**
+ * @ingroup Socket_register_group_W5300
+ * @brief IP Protocol(PROTO) Register(R/W)
+ * @details \ref Sn_PROTO that sets the protocol number field of the IP header at the IP layer. It is
+ * valid only in IPRAW mode, and ignored in other modes.
+ */
+#define Sn_PROTOR(n) Sn_KPALVTR(n)
+
+
+/**
+ * @ingroup Socket_register_group_W5300
+ * @brief IP Type of Service(TOS) Register(R/W)
+ * @details @ref Sn_TOSR configures the TOS(Type Of Service field in IP Header) of Socket n.
+ * It is set before OPEN command.
+ */
+#define Sn_TOSR(n) (_W5300_IO_BASE_ + WIZCHIP_SREG_BLOCK(n) + 0x1C)
+#define Sn_TOS(n) Sn_TOSR(n) ///< For compatible ioLibrary. Refer to Sn_TOSR
+
+/**
+ * @ingroup Socket_register_group_W5300
+ * @brief IP Time to live(TTL) Register(R/W)
+ * @details @ref Sn_TTLR configures the TTL(Time To Live field in IP header) of Socket n.
+ * It is set before OPEN command.
+ */
+#define Sn_TTLR(n) (_W5300_IO_BASE_ + WIZCHIP_SREG_BLOCK(n) + 0x1E)
+#define Sn_TTL(n) Sn_TTLR(n) ///< For compatible ioLibrary. Refer to Sn_TTLR
+
+/**
+ * @ingroup Socket_register_group_W5300
+ * @brief SOCKETn TX write size register(R/W)
+ * @details It sets the byte size of the data written in internal TX memory through @ref Sn_TX_FIFOR.
+ * It is set before SEND or SEND_MAC command, and can't be bigger than internal TX memory
+ * size set by TMSR such as @ref TMS01R, TMS23R and etc.
+ */
+#define Sn_TX_WRSR(n) (_W5300_IO_BASE_ + WIZCHIP_SREG_BLOCK(n) + 0x20)
+
+/**
+ * @ingroup Socket_register_group_W5300
+ * @brief Transmit free memory size register(R)
+ * @details Sn_TX_FSR indicates the free size of Socket n TX Buffer Block. It is initialized to the configured size by TMSR such as @ref TMS01SR.
+ * Data bigger than Sn_TX_FSR should not be saved in the Socket n TX Buffer because the bigger data overwrites the previous saved data not yet sent.
+ * Therefore, check before saving the data to the Socket n TX Buffer, and if data is equal or smaller than its checked size,
+ * transmit the data with SEND/SEND_MAC command after saving the data in Socket n TX buffer. But, if data is bigger than its checked size,
+ * transmit the data after dividing into the checked size and saving in the Socket n TX buffer.
+ */
+#define Sn_TX_FSR(n) (_W5300_IO_BASE_ + WIZCHIP_SREG_BLOCK(n) + 0x0024)
+
+/**
+ * @ingroup Socket_register_group_w5300
+ * @brief Received data size register(R)
+ * @details @ref Sn_RX_RSR indicates the data size received and saved in Socket n RX Buffer.
+ * @ref Sn_RX_RSR does not exceed the RMSR such as @ref RMS01SR and is calculated as the difference between
+ * ?Socket n RX Write Pointer (@ref Sn_RX_WR)and Socket n RX Read Pointer (@ref Sn_RX_RD)
+ */
+#define Sn_RX_RSR(n) (_W5300_IO_BASE_ + WIZCHIP_SREG_BLOCK(n) + 0x0028)
+
+/**
+ * @ingroup Socket_register_group_W5300
+ * @brief Fragment field value in IP header register(R/W)
+ * @details @ref Sn_FRAGR configures the FRAG(Fragment field in IP header).
+ */
+#define Sn_FRAGR(n) (_W5300_IO_BASE_ + WIZCHIP_SREG_BLOCK(n) + 0x002C)
+#define Sn_FRAG(n) Sn_FRAGR(n)
+
+/**
+ * @ingroup Socket_register_group_W5300
+ * @brief SOCKET n TX FIFO regsiter
+ * @details It indirectly accesses internal TX memory of SOCKETn.
+ * The internal TX memory can't be accessed directly by the host, but can be accessed through Sn_TX_FIFOR.
+ * If @ref MR(MT) = '0', only the Host-Write of internal TX memory is allowed through Sn_TX_FIFOR.
+ * But if @ref MR(MT) is '1', both of Host-Read and Host-Write are allowed.
+ */
+#define Sn_TX_FIFOR(n) (_W5300_IO_BASE_ + WIZCHIP_SREG_BLOCK(n) + 0x2E)
+
+/**
+ * @ingroup Socket_register_group_W5300
+ * @brief SOCKET n RX FIFO register
+ * @details It indirectly accesses to internal RX memory of SOCKETn.
+ * The internal RX memory can't be directly accessed by the host, but can be accessed through Sn_RX_FIFOR.
+ * If MR(MT) = '0', only the Host-Read of internal RX memory is allowed through Sn_RX_FIFOR.
+ * But if MR(MT) is '1', both of Host-Read and Host-Write are allowed.
+ */
+#define Sn_RX_FIFOR(n) (_W5300_IO_BASE_ + WIZCHIP_SREG_BLOCK(n) + 0x30)
+
+//#define Sn_TX_SADR(n) (_W5300_IO_BASE_ + WIZCHIP_SREG_BLOCK(n) + 0x32)
+
+//#define Sn_RX_SADR(n) (_W5300_IO_BASE_ + WIZCHIP_SREG_BLOCK(n) + 0x34)
+
+//#define Sn_TX_RD(n) (_W5300_IO_BASE_ + WIZCHIP_SREG_BLOCK(n) + 0x36)
+
+//#define Sn_TX_WR(n) (_W5300_IO_BASE_ + WIZCHIP_SREG_BLOCK(n) + 0x38)
+
+//#define Sn_TX_ACK(n) (_W5300_IO_BASE_ + WIZCHIP_SREG_BLOCK(n) + 0x3A)
+
+//#define Sn_RX_RD(n) (_W5300_IO_BASE_ + WIZCHIP_SREG_BLOCK(n) + 0x3C)
+
+//#define Sn_RX_WR(n) (_W5300_IO_BASE_ + WIZCHIP_SREG_BLOCK(n) + 0x3E)
+
+
+/************************************/
+/* The bit of MR regsiter defintion */
+/************************************/
+#define MR_DBW (1 << 15) /**< Data bus width bit of \ref MR. Read Only. (0 : 8Bit, 1 : 16Bit)*/
+#define MR_MPF (1 << 14) /**< Mac layer pause frame bit of \ref MR. (0 : Disable, 1 : Enable)*/
+#define MR_WDF(X) ((X & 0x07) << 11) /**< Write data fetch time bit of \ref MR. Fetch Data from DATA bus after PLL_CLK * MR_WDF[2:0]*/
+#define MR_RDH (1 << 10) /**< Read data hold time bit of \ref MR. Hold Data on DATA bus during 2 * PLL_CLK after CS high*/
+#define MR_FS (1 << 8) /**< FIFO swap bit of \ref MR. Swap MSB & LSB of \ref Sn_TX_FIFOR & Sn_RX_FIFOR (0 : No swap, 1 : Swap) */
+#define MR_RST (1 << 7) /**< S/W reset bit of \ref MR. (0 : Normal Operation, 1 : Reset (automatically clear after reset))*/
+#define MR_MT (1 << 5) /**< Memory test bit of \ref MR. (0 : Normal, 1 : Internal Socket memory write & read Test)*/
+#define MR_PB (1 << 4) /**< Ping block bit of \ref MR. (0 : Unblock, 1 : Block)*/
+#define MR_PPPoE (1 << 3) /**< PPPoE bit of \ref MR. (0 : No use PPPoE, 1: Use PPPoE)*/
+#define MR_DBS (1 << 2) /**< Data bus swap of \ref MR. Valid only 16bit mode (0 : No swap, 1 : Swap)*/
+#define MR_IND (1 << 0) /**< Indirect mode bit of \ref MR. (0 : Direct mode, 1 : Indirect mode) */
+
+
+/************************************/
+/* The bit of IR regsiter defintion */
+/************************************/
+#define IR_IPCF (1 << 15) /**< IP conflict bit of \ref IR. To clear, Write the bit to '1'. */
+#define IR_DPUR (1 << 14) /**< Destination port unreachable bit of \ref IR. To clear, Write the bit to '1'. */
+#define IR_PPPT (1 << 13) /**< PPPoE terminate bit of \ref IR. To clear, Write the bit to '1'. */
+#define IR_FMTU (1 << 12) /**< Fragment MTU bit of IR. To clear, Write the bit to '1'. */
+#define IR_SnINT(n) (0x01 << n) /**< SOCKETn interrupt occurrence bit of \ref IR. To clear, Clear \ref Sn_IR*/
+
+/*****************************************/
+/* The bit of Pn_BRDYR regsiter defintion*/
+/*****************************************/
+#define Pn_PEN (1 << 7) /**< PIN 'BRDYn' enable bit of Pn_BRDYR. */
+#define Pn_MT (1 << 6) /**< PIN memory type bit of Pn_BRDYR. */
+#define Pn_PPL (1 << 5) /**< PIN Polarity bit of Pn_BRDYR. */
+#define Pn_SN(n) ((n & 0x07) << 0) /**< What socket to monitor. */
+
+
+/***************************************/
+/* The bit of Sn_MR regsiter defintion */
+/***************************************/
+/**
+ * @brief Alignment bit of \ref Sn_MR.
+ * @details It is valid only in the TCP (\ref Sn_MR_TCP) with TCP communication,
+ * when every the received DATA packet size is of even number and set as '1',
+ * data receiving performance can be improved by removing PACKET-INFO(data size) that is attached to every the received DATA packet.
+ */
+#define Sn_MR_ALIGN (1 << 8)
+
+/**
+ * @brief Multicasting bit of \ref Sn_MR
+ * @details It is valid only in UDP (\ref Sn_MR_UDP).
+ * In order to implement multicasting, set the IP address and port number in @ref Sn_DIPR and @ref Sn_DPORTR respectively before "OPEN" command(@ref Sn_CR_OPEN).\n
+ * 0 : Disable, 1 : Enable
+ */
+#define Sn_MR_MULTI (1 << 7)
+
+/**
+ * @brief MAC filter bit of \ref Sn_MR
+ * @details It is valid in MACRAW(@ref Sn_MR_MACRAW).
+ * When this bit is set as ‘1’, W5300 can receive packet that is belong in itself or broadcasting.
+ * When this bit is set as ‘0’, W5300 can receive all packets on Ethernet.
+ * When using the hybrid TCP/IP stack, it is recommended to be set as ‘1’ for reducing the receiving overhead of host. \n
+ * 0 : Disable, 1 : Enable
+ */
+#define Sn_MR_MF (1 << 6)
+
+/**
+ * @brief IGMP version bit of \ref Sn_MR
+ * details It is valid in case of @ref Sn_MR_MULTI='1' and UDP(@ref Sn_MR_UDP).
+ * It configures IGMP version to send IGMP message such as Join/Leave/Report to multicast-group. \n
+ * 0 : IGMPv2, 1 : IGMPv1
+ */
+#define Sn_MR_IGMPv (1 << 5)
+#define Sn_MR_MC Sn_MR_IGMPv ///< For compatible ioLibrary
+
+/**
+ * @brief No delayed ack bit of \ref Sn_MR
+ * @details It is valid in TCP(@ref Sn_MR_TCP).
+ * In case that it is set as '1', ACK packet is transmitted right after receiving DATA packet from the peer.
+ * It is recommended to be set as '1' for TCP performance improvement.
+ * In case that it is set as '0', ACK packet is transmitted after the time set in @ref _RTR_ regardless of DATA packet receipt.\n
+ * 0 : No use, 1 : Use
+ */
+#define Sn_MR_ND (1 << 5)
+
+/**
+ * @brief No mode
+ * @details This configures the protocol mode of Socket n.
+ * @sa Sn_MR
+ */
+#define Sn_MR_CLOSE 0x00
+
+/**
+ * @brief TCP mode
+ * @details This configures the protocol mode of Socket n.
+ * @sa Sn_MR
+ */
+#define Sn_MR_TCP 0x01
+
+/**
+ * @brief UDP mode
+ * @details This configures the protocol mode of Socket n.
+ * @sa Sn_MR
+ */
+#define Sn_MR_UDP 0x02 /**< Protocol bits of \ref Sn_MR. */
+
+/**
+ * @brief IP LAYER RAW mode
+ * @details This configures the protocol mode of Socket n.
+ * @sa Sn_MR
+ */
+#define Sn_MR_IPRAW 0x03 /**< Protocol bits of \ref Sn_MR. */
+
+/**
+ * @brief MAC LAYER RAW mode
+ * @details This configures the protocol mode of Socket 0.
+ * @sa Sn_MR
+ * @note MACRAW mode should be only used in Socket 0.
+ */
+#define Sn_MR_MACRAW 0x04
+
+/**
+ * @brief PPPoE mode
+ * @details This configures the protocol mode of Socket 0.
+ * @sa Sn_MR
+ * @note PPPoE mode should be only used in Socket 0.
+ */
+#define Sn_MR_PPPoE 0x05 /**< Protocol bits of \ref Sn_MR. */
+
+#define SOCK_STREAM Sn_MR_TCP /**< For Berkeley Socket API, Refer to @ref Sn_MR_TCP */
+#define SOCK_DGRAM Sn_MR_UDP /**< For Berkeley Socket API, Refer to @ref Sn_MR_UDP */
+
+
+
+/******************************/
+/* The values of CR defintion */
+/******************************/
+/**
+ * @brief Initialize or open a socket
+ * @details Socket n is initialized and opened according to the protocol selected in Sn_MR(P3:P0).
+ * The table below shows the value of @ref Sn_SR corresponding to @ref Sn_MR.\n
+ *
+ *
\b Sn_MR (P[3:0])
\b Sn_SR
+ *
Sn_MR_CLOSE (000)
+ *
Sn_MR_TCP (001)
SOCK_INIT (0x13)
+ *
Sn_MR_UDP (010)
SOCK_UDP (0x22)
+ *
Sn_MR_IPRAW (010)
SOCK_IPRAW (0x32)
+ *
Sn_MR_MACRAW (100)
SOCK_MACRAW (0x42)
+ *
Sn_MR_PPPoE (101)
SOCK_PPPoE (0x5F)
+ *
+ */
+#define Sn_CR_OPEN 0x01
+
+/**
+ * @brief Wait connection request in TCP mode(Server mode)
+ * @details This is valid only in TCP mode (\ref Sn_MR(P3:P0) = \ref Sn_MR_TCP).
+ * In this mode, Socket n operates as a TCP serverand waits for connection-request (SYN packet) from any TCP client
+ * The @ref Sn_SR changes the state from \ref SOCK_INIT to \ref SOCKET_LISTEN.
+ * When a TCP clientconnection request is successfully established,
+ * the @ref Sn_SR changes from SOCK_LISTEN to SOCK_ESTABLISHED and the @ref Sn_IR(0) becomes
+ * But when a TCP clientconnection request is failed, @ref Sn_IR(3) becomes and the status of @ref Sn_SR changes to SOCK_CLOSED.
+ */
+#define Sn_CR_LISTEN 0x02
+
+/**
+ * @brief Send connection request in TCP mode(Client mode)
+ * @details To connect, a connect-request (SYN packet) is sent to TCP serverconfigured by @ref Sn_DIPR & Sn_DPORT(destination address & port).
+ * If the connect-request is successful, the @ref Sn_SR is changed to @ref SOCK_ESTABLISHED and the Sn_IR(0) becomes \n\n
+ * The connect-request fails in the following three cases.\n
+ * 1. When a @b ARPTO occurs (@ref Sn_IR[3] = '1') because destination hardware address is not acquired through the ARP-process.\n
+ * 2. When a @b SYN/ACK packet is not received and @b TCPTO (Sn_IR(3) = )\n
+ * 3. When a @b RST packet is received instead of a @b SYN/ACK packet. In these cases, @ref Sn_SR is changed to @ref SOCK_CLOSED.
+ * @note This is valid only in TCP mode and operates when Socket n acts as TCP client
+ */
+#define Sn_CR_CONNECT 0x04
+
+/**
+ * @brief Send closing request in TCP mode
+ * @details Regardless of TCP serveror TCP client the DISCON command processes the disconnect-process (b>Active closeor Passive close.\n
+ * @par Active close
+ * it transmits disconnect-request(FIN packet) to the connected peer\n
+ * @par Passive close
+ * When FIN packet is received from peer, a FIN packet is replied back to the peer.\n
+ * @details When the disconnect-process is successful (that is, FIN/ACK packet is received successfully), @ref Sn_SR is changed to @ref SOCK_CLOSED.\n
+ * Otherwise, @b TCPTO occurs (\ref Sn_IR[3]='1') and then @ref Sn_SR is changed to @ref SOCK_CLOSED.
+ * @note Valid only in TCP mode.
+ */
+#define Sn_CR_DISCON 0x08
+
+/**
+ * @brief Close socket
+ * @details @ref Sn_SR is changed to @ref SOCK_CLOSED.
+ */
+#define Sn_CR_CLOSE 0x10
+
+/**
+ * @brief Update TX buffer pointer and send data
+ * @details SEND command transmits all the data in the Socket n TX buffer thru @ref Sn_TX_FIFOR.\n
+ * For more details, please refer to Socket n TX Free Size Register (@ref Sn_TX_FSR) and Socket TX Write Size register (@ref Sn_TX_WRSR).
+ */
+#define Sn_CR_SEND 0x20
+
+/**
+ * @brief Send data with MAC address, so without ARP process
+ * @details The basic operation is same as SEND.\n
+ * Normally SEND command transmits data after destination hardware address is acquired by the automatic ARP-process(Address Resolution Protocol).\n
+ * But SEND_MAC command transmits data without the automatic ARP-process.\n
+ * In this case, the destination hardware address is acquired from @ref Sn_DHAR configured by host, instead of APR-process.
+ * @note Valid only in UDP mode.
+ */
+#define Sn_CR_SEND_MAC 0x21
+
+/**
+ * @brief Send keep alive message
+ * @details It checks the connection status by sending 1byte keep-alive packet.\n
+ * If the peer can not respond to the keep-alive packet during timeout time, the connection is terminated and the timeout interrupt will occur.
+ * @note Valid only in TCP mode.
+ */
+#define Sn_CR_SEND_KEEP 0x22
+
+/**
+ * @brief Update RX buffer pointer and receive data
+ * @details RECV completes the processing of the received data in Socket n RX Buffer thru @ref Sn_RX_FIFOR).\n
+ * For more details, refer to Socket n RX Received Size Register (@ref Sn_RX_RSR) & @ref Sn_RX_FIFOR.
+ */
+#define Sn_CR_RECV 0x40 /**< RECV command value of \ref Sn_CR */
+
+#define Sn_CR_PCON 0x23 /**< PPPoE connection begins by transmitting PPPoE discovery packet. Refer to \ref Sn_CR */
+#define Sn_CR_PDISCON 0x24 /**< Closes PPPoE connection. Refer to \ref Sn_CR */
+#define Sn_CR_PCR 0x25 /**< In each phase, it transmits REQ message. Refer to \ref Sn_CR */
+#define Sn_CR_PCN 0x26 /**< In each phase, it transmits NAK message. Refer to \ref Sn_CR */
+#define Sn_CR_PCJ 0x27 /**< In each phase, it transmits REJECT message. Refer to \ref Sn_CR */
+
+
+/*********************************/
+/* The values of Sn_IR defintion */
+/*********************************/
+#define Sn_IR_PRECV 0x80 /**< It is set in the case that option data which is not supported is received. Refer to \ref Sn_IR */
+#define Sn_IR_PFAIL 0x40 /**< It is set in the case that PAP authentication is failed. Refer to \ref Sn_IR */
+#define Sn_IR_PNEXT 0x20 /**< It is set in the case that the phase is changed during PPPoE connection process. \ref Sn_IR */
+#define Sn_IR_SENDOK 0x10 /**< It is set when SEND command is completed. Refer to \ref Sn_IR */
+#define Sn_IR_TIMEOUT 0x08 /**< It is set when ARPTO or TCPTO is occured. Refer to \ref Sn_IR */
+#define Sn_IR_RECV 0x04 /**< It is set whenever data is received from a peer. Refer to \ref Sn_IR */
+#define Sn_IR_DISCON 0x02 /**< It is set when FIN or FIN/ACK packet is received from a peer. Refer to \ref Sn_IR */
+#define Sn_IR_CON 0x01 /**< It is set one time when the connection is successful and then @ref Sn_SR is changed to @ref SOCK_ESTABLISHED. */
+
+/**********************************/
+/* The values of Sn_SSR defintion */
+/**********************************/
+/**
+ * @brief The state of SOCKET intialized or closed
+ * @details This indicates that Socket n is released.\n
+ * When DICON, CLOSE command is ordered, or when a timeout occurs, it is changed to @ref SOCK_CLOSED regardless of previous status.
+ */
+#define SOCK_CLOSED 0x00
+
+/**
+ * @brief The state of ARP process
+ * @details It is temporary state for getting a peer MAC address when TCP connect or UDP Data Send\n
+ * When DICON, CLOSE command is ordered, or when a timeout occurs, it is changed to @ref SOCK_CLOSED regardless of previous status.
+ */
+#define SOCK_ARP 0x01 /**< ARP-request is transmitted in order to acquire destination hardware address. */
+
+/**
+ * @brief Initiate state in TCP.
+ * @details This indicates Socket n is opened with TCP mode.\n
+ * It is changed to @ref SOCK_INIT when \ref Sn_MR(P[3:0]) = '001' and OPEN command(\ref Sn_CR_OPEN) is ordered.\n
+ * After SOCK_INIT, user can use LISTEN(@ref Sn_CR_LISTEN)/CONNECT(@ref Sn_CR_CONNET) command.
+ */
+#define SOCK_INIT 0x13
+
+/**
+ * @brief Listen state
+ * @details This indicates Socket n is operating as TCP servermode and waiting for connection-request (SYN packet) from a peer TCP client.\n
+ * It will change to @ref SOCK_ESTALBLISHED when the connection-request is successfully accepted.\n
+ * Otherwise it will change to @ref SOCK_CLOSED after TCPTO (@ref Sn_IR_TIMEOUT = '1') is occurred.
+ */
+#define SOCK_LISTEN 0x14
+
+/**
+ * @brief Connection state
+ * @details This indicates Socket n sent the connect-request packet (SYN packet) to a peer.\n
+ * It is temporarily shown when @ref Sn_SR is changed from @ref SOCK_INIT to @ref SOCK_ESTABLISHED by @ref Sn_CR_CONNECT command.\n
+ * If connect-accept(SYN/ACK packet) is received from the peer at SOCK_SYNSENT, it changes to @ref SOCK_ESTABLISHED.\n
+ * Otherwise, it changes to @ref SOCK_CLOSED after TCPTO (@ref Sn_IR_TIMEOUT = '1') is occurred.
+ */
+#define SOCK_SYNSENT 0x15
+
+/**
+ * @brief Connection state
+ * @details It indicates Socket n successfully received the connect-request packet (SYN packet) from a peer.\n
+ * If socket n sends the response (SYN/ACK packet) to the peer successfully, it changes to @ref SOCK_ESTABLISHED. \n
+ * If not, it changes to @ref SOCK_CLOSED after timeout (@ref Sn_IR_TIMEOUT = '1') is occurred.
+ */
+#define SOCK_SYNRECV 0x16
+
+/**
+ * @brief Success to connect
+ * @details This indicates the status of the connection of Socket n.\n
+ * It changes to @ref SOCK_ESTABLISHED when the TCP SERVERprocessed the SYN packet from the TCP CLIENTduring @ref SOCK_LISTEN, or
+ * when the @ref Sn_CR_CONNECT command is successful.\n
+ * During @ref SOCK_ESTABLISHED, DATA packet can be transferred using @ref Sn_CR_SEND or @ref Sn_CR_RECV command.
+ */
+#define SOCK_ESTABLISHED 0x17
+
+/**
+ * @brief Closing state
+ * @details These indicate Socket n is closing.\n
+ * These are shown in disconnect-process such as active-close and passive-close.\n
+ * When Disconnect-process is successfully completed, or when timeout(@ref Sn_CR_TIMTEOUT = '1') is occurred, these change to @ref SOCK_CLOSED.
+ */
+#define SOCK_FIN_WAIT 0x18
+
+/**
+ * @brief Closing state
+ * @details These indicate Socket n is closing.\n
+ * These are shown in disconnect-process such as active-close and passive-close.\n
+ * When Disconnect-process is successfully completed, or when timeout occurs, these change to @ref SOCK_CLOSED.
+ */
+#define SOCK_CLOSING 0x1A
+
+/**
+ * @brief Closing state
+ * @details These indicate Socket n is closing.\n
+ * These are shown in disconnect-process such as active-close and passive-close.\n
+ * When Disconnect-process is successfully completed, or when timeout occurs, these change to @ref SOCK_CLOSED.
+ */
+#define SOCK_TIME_WAIT 0x1B
+
+/**
+ * @brief Closing state
+ * @details This indicates Socket n received the disconnect-request (FIN packet) from the connected peer.\n
+ * This is half-closing status, and data can be transferred.\n
+ * For full-closing, @ref Sn_CR_DISCON command is used. But For just-closing, @ref Sn_CR_CLOSE command is used.
+ */
+#define SOCK_CLOSE_WAIT 0x1C
+
+/**
+ * @brief Closing state
+ * @details This indicates Socket n is waiting for the response (FIN/ACK packet) to the disconnect-request (FIN packet) by passive-close.\n
+ * It changes to @ref SOCK_CLOSED when Socket n received the response successfully, or when timeout (@ref Sn_IR_TIMEOUT = '1') is occurred.
+ */
+#define SOCK_LAST_ACK 0x1D
+
+/**
+ * @brief UDP socket
+ * @details This indicates Socket n is opened in UDP mode(@ref Sn_MR(P[3:0]) = '010').\n
+ * It changes to SOCK_UDP when @ref Sn_MR(P[3:0]) = '010' and @ref Sn_CR_OPEN command is ordered.\n
+ * Unlike TCP mode, data can be transfered without the connection-process.
+ */
+#define SOCK_UDP 0x22
+
+/**
+ * @brief IP raw mode socket
+ * @details TThe socket is opened in IPRAW mode. The SOCKET status is change to SOCK_IPRAW when @ref Sn_MR (P3:P0) is
+ * Sn_MR_IPRAW and @ref Sn_CR_OPEN command is used.\n
+ * IP Packet can be transferred without a connection similar to the UDP mode.
+*/
+#define SOCK_IPRAW 0x32
+
+/**
+ * @brief MAC raw mode socket
+ * @details This indicates Socket 0 is opened in MACRAW mode (@ref Sn_MR(P[3:0]) = '100' and n = 0) and is valid only in Socket 0.\n
+ * It changes to SOCK_MACRAW when @ref Sn_MR(P[3:0] = 100)and @ ref Sn_CR_OPEN command is ordered.\n
+ * Like UDP mode socket, MACRAW mode Socket 0 can transfer a MAC packet (Ethernet frame) without the connection-process.
+ */
+#define SOCK_MACRAW 0x42 /**< SOCKET0 is open as MACRAW mode. */
+
+/**
+ * @brief PPPoE mode socket
+ * @details It is the status that SOCKET0 is opened as PPPoE mode.
+ * It is changed to SOCK_PPPoE in case of @ref Sn_CR_OPEN command is ordered and @ref Sn_MR(P3:P0)= @ref Sn_MR_PPPoE\n
+ * It is temporarily used at the PPPoE connection.
+ */
+#define SOCK_PPPoE 0x5F /**< SOCKET0 is open as PPPoE mode. */
+
+/* IP PROTOCOL */
+#define IPPROTO_IP 0 //< Dummy for IP
+#define IPPROTO_ICMP 1 //< Control message protocol
+#define IPPROTO_IGMP 2 //< Internet group management protocol
+#define IPPROTO_GGP 3 //< Gateway^2 (deprecated)
+#define IPPROTO_TCP 6 //< TCP
+#define IPPROTO_PUP 12 //< PUP
+#define IPPROTO_UDP 17 //< UDP
+#define IPPROTO_IDP 22 //< XNS idp
+#define IPPROTO_ND 77 //< UNOFFICIAL net disk protocol
+#define IPPROTO_RAW 255 //< Raw IP packet
+
+
+/**
+ * @brief Enter a critical section
+ *
+ * @details It is provided to protect your shared code which are executed without distribution. \n \n
+ *
+ * In non-OS environment, It can be just implemented by disabling whole interrupt.\n
+ * In OS environment, You can replace it to critical section api supported by OS.
+ *
+ * \sa WIZCHIP_READ(), WIZCHIP_WRITE()
+ * \sa WIZCHIP_CRITICAL_EXIT()
+ */
+#define WIZCHIP_CRITICAL_ENTER() WIZCHIP.CRIS._enter()
+
+#ifdef _exit
+#undef _exit
+#endif
+
+/**
+ * @brief Exit a critical section
+ *
+ * @details It is provided to protect your shared code which are executed without distribution. \n\n
+ *
+ * In non-OS environment, It can be just implemented by disabling whole interrupt. \n
+ * In OS environment, You can replace it to critical section api supported by OS.
+ *
+ * @sa WIZCHIP_READ(), WIZCHIP_WRITE()
+ * @sa WIZCHIP_CRITICAL_ENTER()
+ */
+#define WIZCHIP_CRITICAL_EXIT() WIZCHIP.CRIS._exit()
+
+////////////////////////
+// Basic I/O Function //
+////////////////////////
+
+/**
+ * @ingroup Basic_IO_function_W5300
+ * @brief It reads 1 byte value from a register.
+ * @param AddrSel Register address
+ * @return The value of register
+ */
+uint16_t WIZCHIP_READ (uint32_t AddrSel);
+
+/**
+ * @ingroup Basic_IO_function_W5300
+ * @brief It writes 1 byte value to a register.
+ * @param AddrSel Register address
+ * @param wb Write data
+ * @return void
+ */
+void WIZCHIP_WRITE(uint32_t AddrSel, uint16_t wb );
+
+/***********************************
+ * COMMON Register Access Function *
+ ***********************************/
+
+/**
+ * @ingroup Common_register_access_function_W5300
+ * @brief Set Mode Register
+ * @param (@ref iodata_t)mr The value to be set.
+ * @sa getMR()
+ */
+#if (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_)
+ #if (_WIZCHIP_IO_BUS_WIDTH_ == 8)
+ #define setMR(mr) \
+ (*((uint8_t*)MR) = (uint8_t)((mr) >> 8)); (*((uint8_t*)WIZCHIP_OFFSET_INC(MR,1)) = (uint8_t)((mr) & 0xFF))
+ #elif (_WIZCHIP_IO_BUS_WIDTH_ == 16)
+ #define setMR(mr) (*((uint16_t*)MR) = (uint16_t)((mr) & 0xFFFF))
+ #else
+ #error "Unknown _WIZCHIP_IO_BUS_WIDTH_. You should be define _WIZCHIP_IO_BUS_WIDTH as 8 or 16."
+ #endif
+#else
+ #error "Unknown _WIZCHIP_IO_MODE_"
+#endif
+
+/**
+ * @ingroup Common_register_access_function_W5300
+ * @brief Get @ref MR.
+ * @return @ref iodata_t. The value of Mode register.
+ * @sa setMR()
+ */
+#if (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_)
+ #if (_WIZCHIP_IO_BUS_WIDTH_ == 8)
+ #define getMR() (((uint16_t)(*((uint8_t*)MR)) << 8) + (((uint16_t)(*((uint8_t*)WIZCHIP_OFFSET_INC(MR,1)))) & 0x00FF))
+ #elif(_WIZCHIP_IO_BUS_WIDTH_ == 16)
+ #define getMR() (*((uint16_t*)MR))
+ #else
+ #error "Unknown _WIZCHIP_IO_BUS_WIDTH_. You should be define _WIZCHIP_IO_BUS_WIDTH as 8 or 16."
+ #endif
+#else
+ #error "Unknown _WIZCHIP_IO_MODE_"
+#endif
+
+/**
+ * @ingroup Common_register_access_function_W5300
+ * @brief Set \ref IR register
+ * @param (uint16_t)ir Value to set \ref IR register.
+ * @sa getIR()
+ */
+#define setIR(ir) \
+ WIZCHIP_WRITE(IR, ir & 0xF0FF)
+
+/**
+ * @ingroup Common_register_access_function_W5300
+ * @brief Get \ref IR register
+ * @return uint8_t. Value of \ref IR register.
+ * @sa setIR()
+ */
+#define getIR() \
+ (WIZCHIP_READ(IR) & 0xF0FF)
+
+
+/**
+ * @ingroup Common_register_access_function_W5300
+ * @brief Set \ref _IMR_ register
+ * @param (uint16_t)imr Value to set @ref _IMR_ register.
+ * @sa getIMR()
+ */
+#define setIMR(imr) \
+ WIZCHIP_WRITE(_IMR_, imr & 0xF0FF)
+
+/**
+ * @ingroup Common_register_access_function_W5300
+ * @brief Get \ref _IMR_ register
+ * @return uint16_t. Value of \ref IR register.
+ * @sa setIMR()
+ */
+#define getIMR() \
+ (WIZCHIP_READ(_IMR_) & 0xF0FF)
+
+/**
+ * @ingroup Common_register_access_function_W5300
+ * @brief Set local MAC address
+ * @param (uint8_t*)shar Pointer variable to set local MAC address. It should be allocated 6 bytes.
+ * @sa getSHAR()
+ */
+#define setSHAR(shar) { \
+ WIZCHIP_WRITE(SHAR, (((uint16_t)((shar)[0])) << 8) + (((uint16_t)((shar)[1])) & 0x00FF)); \
+ WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(SHAR,2), (((uint16_t)((shar)[2])) << 8) + (((uint16_t)((shar)[3])) & 0x00FF)); \
+ WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(SHAR,4), (((uint16_t)((shar)[4])) << 8) + (((uint16_t)((shar)[5])) & 0x00FF)); \
+ }
+
+/**
+ * @ingroup Common_register_access_function
+ * @brief Get local MAC address
+ * @param (uint8_t*)shar Pointer variable to get local MAC address. It should be allocated 6 bytes.
+ * @sa setSHAR()
+ */
+#define getSHAR(shar) { \
+ (shar)[0] = (uint8_t)(WIZCHIP_READ(SHAR) >> 8); \
+ (shar)[1] = (uint8_t)(WIZCHIP_READ(SHAR)); \
+ (shar)[2] = (uint8_t)(WIZCHIP_READ(WIZCHIP_OFFSET_INC(SHAR,2)) >> 8); \
+ (shar)[3] = (uint8_t)(WIZCHIP_READ(WIZCHIP_OFFSET_INC(SHAR,2))); \
+ (shar)[4] = (uint8_t)(WIZCHIP_READ(WIZCHIP_OFFSET_INC(SHAR,4)) >> 8); \
+ (shar)[5] = (uint8_t)(WIZCHIP_READ(WIZCHIP_OFFSET_INC(SHAR,4))); \
+ }
+
+/**
+ * @ingroup Common_register_access_function_W5300
+ * @brief Set gateway IP address
+ * @param (uint8_t*)gar Pointer variable to set gateway IP address. It should be allocated 4 bytes.
+ * @sa getGAR()
+ */
+#define setGAR(gar) { \
+ WIZCHIP_WRITE(GAR, (((uint16_t)((gar)[0])) << 8) + (((uint16_t)((gar)[1])) & 0x00FF)); \
+ WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(GAR,2), (((uint16_t)((gar)[2])) << 8) + (((uint16_t)((gar)[3])) & 0x00FF)); \
+ }
+
+/**
+ * @ingroup Common_register_access_function_W5300
+ * @brief Get gateway IP address
+ * @param (uint8_t*)gar Pointer variable to get gateway IP address. It should be allocated 4 bytes.
+ * @sa setGAR()
+ */
+#define getGAR(gar) { \
+ (gar)[0] = (uint8_t)(WIZCHIP_READ(GAR) >> 8); \
+ (gar)[1] = (uint8_t)(WIZCHIP_READ(GAR)); \
+ (gar)[2] = (uint8_t)(WIZCHIP_READ(WIZCHIP_OFFSET_INC(GAR,2)) >> 8); \
+ (gar)[3] = (uint8_t)(WIZCHIP_READ(WIZCHIP_OFFSET_INC(GAR,2))); \
+ }
+
+/**
+ * @ingroup Common_register_access_function_W5300
+ * @brief Set subnet mask address
+ * @param (uint8_t*)subr Pointer variable to set subnet mask address. It should be allocated 4 bytes.
+ * @sa getSUBR()
+ */
+#define setSUBR(subr) { \
+ WIZCHIP_WRITE(SUBR, (((uint16_t)((subr)[0])) << 8) + (((uint16_t)((subr)[1])) & 0x00FF)); \
+ WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(SUBR,2), (((uint16_t)((subr)[2])) << 8) + (((uint16_t)((subr)[3])) & 0x00FF)); \
+ }
+
+/**
+ * @ingroup Common_register_access_function_W5300
+ * @brief Get subnet mask address
+ * @param (uint8_t*)subr Pointer variable to get subnet mask address. It should be allocated 4 bytes.
+ * @sa setSUBR()
+ */
+#define getSUBR(subr) { \
+ (subr)[0] = (uint8_t)(WIZCHIP_READ(SUBR) >> 8); \
+ (subr)[1] = (uint8_t)(WIZCHIP_READ(SUBR)); \
+ (subr)[2] = (uint8_t)(WIZCHIP_READ(WIZCHIP_OFFSET_INC(SUBR,2)) >> 8); \
+ (subr)[3] = (uint8_t)(WIZCHIP_READ(WIZCHIP_OFFSET_INC(SUBR,2))); \
+ }
+
+/**
+ * @ingroup Common_register_access_function_W5300
+ * @brief Set local IP address
+ * @param (uint8_t*)sipr Pointer variable to set local IP address. It should be allocated 4 bytes.
+ * @sa getSIPR()
+ */
+#define setSIPR(sipr) { \
+ WIZCHIP_WRITE(SIPR, (((uint16_t)((sipr)[0])) << 8) + (((uint16_t)((sipr)[1])) & 0x00FF)); \
+ WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(SIPR,2), (((uint16_t)((sipr)[2])) << 8) + (((uint16_t)((sipr)[3])) & 0x00FF)); \
+ }
+
+/**
+ * @ingroup Common_register_access_function_W5300
+ * @brief Get local IP address
+ * @param (uint8_t*)sipr Pointer variable to get local IP address. It should be allocated 4 bytes.
+ * @sa setSIPR()
+ */
+#define getSIPR(sipr) { \
+ (sipr)[0] = (uint8_t)(WIZCHIP_READ(SIPR) >> 8); \
+ (sipr)[1] = (uint8_t)(WIZCHIP_READ(SIPR)); \
+ (sipr)[2] = (uint8_t)(WIZCHIP_READ(WIZCHIP_OFFSET_INC(SIPR,2)) >> 8); \
+ (sipr)[3] = (uint8_t)(WIZCHIP_READ(WIZCHIP_OFFSET_INC(SIPR,2))); \
+ }
+
+
+/**
+ * @ingroup Common_register_access_function_W5300
+ * @brief Set @ref _RTR_ register
+ * @param (uint16_t)rtr Value to set @ref _RTR_ register.
+ * @sa getRTR()
+ */
+#define setRTR(rtr) \
+ WIZCHIP_WRITE(_RTR_, rtr)
+
+/**
+ * @ingroup Common_register_access_function_W5300
+ * @brief Get @ref _RTR_ register
+ * @return uint16_t. Value of @ref _RTR_ register.
+ * @sa setRTR()
+ */
+#define getRTR() \
+ WIZCHIP_READ(_RTR_)
+
+/**
+ * @ingroup Common_register_access_function_W5300
+ * @brief Set @ref _RCR_ register
+ * @param (uint8_t)rcr Value to set @ref _RCR_ register.
+ * @sa getRCR()
+ */
+#define setRCR(rcr) \
+ WIZCHIP_WRITE(_RCR_, ((uint16_t)rcr)&0x00FF)
+
+/**
+ * @ingroup Common_register_access_function_W5300
+ * @brief Get @ref _RCR_ register
+ * @return uint8_t. Value of @ref _RCR_ register.
+ * @sa setRCR()
+ */
+#define getRCR() \
+ ((uint8_t)(WIZCHIP_READ(_RCR_) & 0x00FF))
+
+/**
+ * @ingroup Common_register_access_function_W5300
+ * @brief Set @ref TMS01R register
+ * @param (uint16_t)tms01r Value to set @ref TMS01R register. The lower socket memory size is located at MSB of tms01r.
+ * @sa getTMS01R()
+ */
+#define setTMS01R(tms01r) \
+ WIZCHIP_WRITE(TMS01R,tms01r)
+
+/**
+ * @ingroup Common_register_access_function_W5300
+ * @brief Get @ref TMS01R register
+ * @return uint16_t. Value of @ref TMS01R register.
+ * @sa setTMS01R()
+ */
+#define getTMS01R() \
+ WIZCHIP_READ(TMS01R)
+
+/**
+ * @ingroup Common_register_access_function_W5300
+ * @brief Set @ref TMS23R register
+ * @param (uint16_t)tms23r Value to set @ref TMS23R register. The lower socket memory size is located at MSB of tms01r.
+ * @sa getTMS23R()
+ */
+#define setTMS23R(tms23r) \
+ WIZCHIP_WRITE(TMS23R,tms23r)
+
+/**
+ * @ingroup Common_register_access_function_W5300
+ * @brief Get @ref TMS23R register
+ * @return uint16_t. Value of @ref TMS23R register.
+ * @sa setTMS23R()
+ */
+#define getTMS23R() \
+ WIZCHIP_READ(TMS23R)
+
+/**
+ * @ingroup Common_register_access_function_W5300
+ * @brief Set @ref TMS45R register
+ * @param (uint16_t)tms45r Value to set @ref TMS45R register. The lower socket memory size is located at MSB of tms45r.
+ * @sa getTMS45R()
+ */
+#define setTMS45R(tms45r) \
+ WIZCHIP_WRITE(TMS45R,tms45r)
+
+/**
+ * @ingroup Common_register_access_function_W5300
+ * @brief Get @ref TMS45R register
+ * @return uint16_t. Value of @ref TMS45R register.
+ * @sa setTMS45R()
+ */
+#define getTMS45R() \
+ WIZCHIP_READ(TMS45R)
+
+/**
+ * @ingroup Common_register_access_function_W5300
+ * @brief Set @ref TMS67R register
+ * @param (uint16_t)tms67r Value to set @ref TMS67R register. The lower socket memory size is located at MSB of tms67r.
+ * @sa getTMS67R()
+ */
+#define setTMS67R(tms67r) \
+ WIZCHIP_WRITE(TMS67R,tms67r)
+
+/**
+ * @ingroup Common_register_access_function_W5300
+ * @brief Get @ref TMS67R register
+ * @return uint16_t. Value of @ref TMS67R register.
+ * @sa setTMS67R()
+ */
+#define getTMS67R() \
+ WIZCHIP_READ(TMS67R)
+
+/**
+ * @ingroup Common_register_access_function_W5300
+ * @brief Set @ref TMSR0 ~ @ref TMSR7 register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @param (uint8_t)tmsr Value to set @ref TMSR0 ~@ref TMSR7 register.
+ * @sa getTMSR()
+ */
+void setTMSR(uint8_t sn,uint8_t tmsr);
+#define setSn_TXBUF_SIZE(sn, tmsr) setTMSR(sn, tmsr) ///< For compatible ioLibrary
+
+/**
+ * @ingroup Common_register_access_function_W5300
+ * @brief Get @ref TMSR0 ~ @ref TMSR7 register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @return uint8_t. Value of @ref TMSR0 ~ @ref TMSR7
+ * @sa getTMSR()
+ */
+uint8_t getTMSR(uint8_t sn);
+#define getSn_TXBUF_SIZE(sn) getTMSR(sn) ///< For compatible ioLibrary
+
+/**
+ * @ingroup Common_register_access_function_W5300
+ * @brief Set @ref RMS01R register
+ * @param (uint16_t)rms01r Value to set @ref RMS01R register. The lower socket memory size is located at MSB of rms01r.
+ * @sa getRMS01R()
+ */
+#define setRMS01R(rms01r) \
+ WIZCHIP_WRITE(RMS01R,rms01r)
+
+/**
+ * @ingroup Common_register_access_function_W5300
+ * @brief Get @ref RMS01R register
+ * @return uint16_t. Value of @ref RMS01R register.
+ * @sa setRMS01R()
+ */
+#define getRMS01R() \
+ WIZCHIP_READ(RMS01R)
+
+/**
+ * @ingroup Common_register_access_function_W5300
+ * @brief Set @ref RMS23R register
+ * @param (uint16_t)rms23r Value to set @ref RMS23R register. The lower socket memory size is located at MSB of rms01r.
+ * @sa getRMS23R()
+ */
+#define setRMS23R(rms23r) \
+ WIZCHIP_WRITE(RMS23R,rms23r)
+
+/**
+ * @ingroup Common_register_access_function_W5300
+ * @brief Get @ref RMS23R register
+ * @return uint16_t. Value of @ref RMS23R register.
+ * @sa setRMS23R()
+ */
+#define getRMS23R() \
+ WIZCHIP_READ(RMS23R)
+
+/**
+ * @ingroup Common_register_access_function_W5300
+ * @brief Set @ref RMS45R register
+ * @param (uint16_t)rms45r Value to set @ref RMS45R register. The lower socket memory size is located at MSB of rms45r.
+ * @sa getRMS45R()
+ */
+#define setRMS45R(rms45r) \
+ WIZCHIP_WRITE(RMS45R,rms45r)
+
+/**
+ * @ingroup Common_register_access_function_W5300
+ * @brief Get @ref RMS45R register
+ * @return uint16_t. Value of @ref RMS45R register.
+ * @sa setRMS45R()
+ */
+#define getRMS45R() \
+ WIZCHIP_READ(RMS45R)
+
+/**
+ * @ingroup Common_register_access_function_W5300
+ * @brief Set @ref RMS67R register
+ * @param (uint16_t)rms67r Value to set @ref RMS67R register. The lower socket memory size is located at MSB of rms67r.
+ * @sa getRMS67R()
+ */
+#define setRMS67R(rms67r) \
+ WIZCHIP_WRITE(RMS67R,rms67r)
+
+/**
+ * @ingroup Common_register_access_function_W5300
+ * @brief Get @ref RMS67R register
+ * @return uint16_t. Value of @ref RMS67R register.
+ * @sa setRMS67R()
+ */
+#define getRMS67R() \
+ WIZCHIP_READ(RMS67R)
+
+/**
+ * @ingroup Common_register_access_function_W5300
+ * @brief Set @ref RMS01R ~ @ref RMS67R register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @param (uint8_t)rmsr Value to set @ref RMSR0 ~@ref RMSR7 register.
+ * @sa getTMSR()
+ */
+void setRMSR(uint8_t sn,uint8_t rmsr);
+#define setSn_RXBUF_SIZE(sn,rmsr) setRMSR(sn, rmsr) ///< For compatible ioLibrary
+
+/**
+ * @ingroup Common_register_access_function_W5300
+ * @brief Get @ref RMS01R ~ @ref RMS67R register
+ * @param (uint8_t)sn Socket number. It shoudl be 0 ~ 7.
+ * @return uint8_t. Value of @ref RMSR0 ~ @ref RMSR7 register.
+ * @sa setRMSR()
+ */
+uint8_t getRMSR(uint8_t sn);
+#define getSn_RXBUF_SIZE(sn) getRMSR(sn) ///< For compatible ioLibrary
+
+/**
+ * @ingroup Common_register_access_function_W5300
+ * @brief Set @ref MTYPER register
+ * @param (uint16_t)mtyper Value to set @ref MTYPER register.
+ * @sa getMTYPER()
+ */
+#define setMTYPER(mtype) \
+ WIZCHIP_WRITE(MTYPER, mtype)
+
+/**
+ * @ingroup Common_register_access_function_W5300
+ * @brief Get @ref MTYPER register
+ * @return uint16_t. Value of @ref MTYPER register.
+ * @sa setMTYPER()
+ */
+#define getMTYPER() \
+ WIZCHIP_READ(MTYPER)
+
+/**
+ * @ingroup Common_register_access_function_W5300
+ * @brief Get @ref RATR register
+ * @return uint16_t. Value of @ref PATR register.
+ */
+#define getPATR() \
+ WIZCHIP_READ(PATR)
+
+/**
+ * @ingroup Common_register_access_function_W5300
+ * @brief Set @ref PTIMER register
+ * @param (uint8_t)ptimer Value to set @ref PTIMER register.
+ * @sa getPTIMER()
+ */
+#define setPTIMER(ptimer) \
+ WIZCHIP_WRITE(PTIMER, ((uint16_t)ptimer) & 0x00FF)
+
+/**
+ * @ingroup Common_register_access_function_W5300
+ * @brief Get @ref PTIMER register
+ * @return uint8_t. Value of @ref PTIMER register.
+ * @sa setPTIMER()
+ */
+#define getPTIMER() \
+ ((uint8_t)(WIZCHIP_READ(PTIMER) & 0x00FF))
+
+/**
+ * @ingroup Common_register_access_function_W5300
+ * @brief Set @ref PMAGIC register
+ * @param (uint8_t)pmagic Value to set @ref PMAGIC register.
+ * @sa getPMAGIC()
+ */
+#define setPMAGIC(pmagic) \
+ WIZCHIP_WRITE(PMAGIC, ((uint16_t)pmagic) & 0x00FF)
+
+/**
+ * @ingroup Common_register_access_function_W5300
+ * @brief Get @ref PMAGIC register
+ * @return uint8_t. Value of @ref PMAGIC register.
+ * @sa setPMAGIC()
+ */
+#define getPMAGIC() \
+ ((uint8_t)(WIZCHIP_READ(PMAGIC) & 0x00FF))
+
+/**
+ * @ingroup Common_register_access_function_W5300
+ * @brief Get @ref PSID register
+ * @return uint16_t. Value of @ref PSID register.
+ */
+#define getPSIDR() \
+ WIZCHIP_READ(PSIDR)
+
+/**
+ * @ingroup Common_register_access_function_W5300
+ * @brief Get @ref PDHAR register
+ * @param (uint8_t*)pdhar Pointer variable to PPP destination MAC register address. It should be allocated 6 bytes.
+ */
+#define getPDHAR(pdhar) { \
+ (pdhar)[0] = (uint8_t)(WIZCHIP_READ(PDHAR) >> 8); \
+ (pdhar)[1] = (uint8_t)(WIZCHIP_READ(PDHAR)); \
+ (pdhar)[2] = (uint8_t)(WIZCHIP_READ(WIZCHIP_OFFSET_INC(PDHAR,2)) >> 8); \
+ (pdhar)[3] = (uint8_t)(WIZCHIP_READ(WIZCHIP_OFFSET_INC(PDHAR,2))); \
+ (pdhar)[4] = (uint8_t)(WIZCHIP_READ(WIZCHIP_OFFSET_INC(PDHAR,4)) >> 8); \
+ (pdhar)[5] = (uint8_t)(WIZCHIP_READ(WIZCHIP_OFFSET_INC(PDHAR,4))); \
+ }
+
+/**
+ * @ingroup Common_register_access_function_W5300
+ * @brief Get unreachable IP address. @ref UIPR
+ * @param (uint8_t*)uipr Pointer variable to get unreachable IP address. It should be allocated 4 bytes.
+ */
+#define getUIPR(uipr) { \
+ (uipr)[0] = (uint8_t)(WIZCHIP_READ(UIPR) >> 8); \
+ (uipr)[1] = (uint8_t)(WIZCHIP_READ(UIPR)); \
+ (uipr)[2] = (uint8_t)(WIZCHIP_READ(WIZCHIP_OFFSET_INC(UIPR,2)) >> 8); \
+ (uipr)[3] = (uint8_t)(WIZCHIP_READ(WIZCHIP_OFFSET_INC(UIPR,2))); \
+ }
+
+/**
+ * @ingroup Common_register_access_function_W5300
+ * @brief Get @ref UPORTR register
+ * @return uint16_t. Value of @ref UPORTR register.
+ */
+#define getUPORTR() \
+ WIZCHIP_READ(UPORTR)
+
+/**
+ * @ingroup Common_register_access_function_W5300
+ * @brief Get @ref FMTUR register
+ * @return uint16_t. Value of @ref FMTUR register.
+ */
+#define getFMTUR() \
+ WIZCHIP_READ(FMTUR)
+
+
+/**
+ * @ingroup Common_register_access_function_W5300
+ * @brief Get @ref Pn_BRDYR register
+ * @return uint8_t. Value of @ref Pn_BRDYR register.
+ */
+#define getPn_BRDYR(p) \
+ ((uint8_t)(WIZCHIP_READ(Pn_BRDYR(p)) & 0x00FF))
+
+/**
+ * @ingroup Common_register_access_function_W5300
+ * @brief Set @ref Pn_BRDYR register
+ * @param p Pin number (p = 0,1,2,3)
+ * @param brdyr Set a value @ref Pn_BRDYR(p).
+ */
+#define setPn_BRDYR(p, brdyr) \
+ WIZCHIP_WRITE(Pn_BRDYR(p), brdyr & 0x00E7)
+
+/**
+ * @ingroup Common_register_access_function_W5300
+ * @brief Get @ref Pn_BDPTHR register
+ * @param p Pin number (p = 0,1,2,3)
+ * @return uint16_t. Value of @ref Pn_BDPTHR register.
+ */
+#define getPn_BDPTHR(p) \
+ WIZCHIP_READ(Pn_BDPTHR(p))
+
+/**
+ * @ingroup Common_register_access_function_W5300
+ * @brief Set @ref Pn_BDPTHR register
+ * @param p Pin number (p = 0,1,2,3)
+ * @param bdpthr Value of @ref Pn_BDPTHR
+ */
+#define setPn_BDPTHR(p, bdpthr) \
+ WIZCHIP_WRITE(Pn_BDPTHR(p),bdpthr)
+
+
+/**
+ * @ingroup Common_register_access_function_W5300
+ * @brief Get @ref IDR register
+ * @return uint16_t. Always 0x5300.
+ */
+#define getIDR() \
+ WIZCHIP_READ(IDR)
+
+
+/***********************************
+ * SOCKET Register Access Function *
+ ***********************************/
+
+/**
+ * @ingroup Socket_register_access_function_W5300
+ * @brief Set @ref Sn_MR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @param (uint8_t)mr Value to set @ref Sn_MR
+ * @sa getSn_MR()
+ */
+#define setSn_MR(sn, mr) \
+ WIZCHIP_WRITE(Sn_MR(sn),mr)
+
+/**
+ * @ingroup Socket_register_access_function_W5300
+ * @brief Get @ref Sn_MR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @return uint8_t. Value of @ref Sn_MR.
+ * @sa setSn_MR()
+ */
+#define getSn_MR(sn) \
+ WIZCHIP_READ(Sn_MR(sn))
+
+/**
+ * @ingroup Socket_register_access_function_W5300
+ * @brief Set @ref Sn_CR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @param (uint8_t)cr Value to set @ref Sn_CR
+ * @sa getSn_CR()
+ */
+#define setSn_CR(sn, cr) \
+ WIZCHIP_WRITE(Sn_CR(sn), ((uint16_t)cr) & 0x00FF)
+
+/**
+ * @ingroup Socket_register_access_function_W5300
+ * @brief Get @ref Sn_CR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @return uint8_t. Value of @ref Sn_CR.
+ * @sa setSn_CR()
+ */
+#define getSn_CR(sn) \
+ ((uint8_t)WIZCHIP_READ(Sn_CR(sn)))
+
+/**
+ * @ingroup Socket_register_access_function_W5300
+ * @brief Set @ref Sn_IMR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @param (uint8_t)imr Value to set @ref Sn_IMR
+ * @sa getSn_IMR()
+ */
+#define setSn_IMR(sn, imr) \
+ WIZCHIP_WRITE(Sn_IMR(sn), ((uint16_t)imr) & 0x00FF)
+
+/**
+ * @ingroup Socket_register_access_function_W5300
+ * @brief Get @ref Sn_IMR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @return uint8_t. Value of @ref Sn_IMR.
+ * @sa setSn_IMR()
+ */
+#define getSn_IMR(sn) \
+ ((uint8_t)WIZCHIP_READ(Sn_IMR(sn)))
+
+/**
+ * @ingroup Socket_register_access_function_W5300
+ * @brief Set @ref Sn_IR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @param (uint8_t)ir Value to set @ref Sn_IR
+ * @sa getSn_IR()
+ */
+#define setSn_IR(sn, ir) \
+ WIZCHIP_WRITE(Sn_IR(sn), ((uint16_t)ir) & 0x00FF)
+
+/**
+ * @ingroup Socket_register_access_function_W5300
+ * @brief Get @ref Sn_IR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @return uint8_t. Value of @ref Sn_IR.
+ * @sa setSn_IR()
+ */
+#define getSn_IR(sn) \
+ ((uint8_t)WIZCHIP_READ(Sn_IR(sn)))
+
+/**
+ * @ingroup Socket_register_access_function_W5300
+ * @brief Get @ref Sn_SR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @return uint8_t. Value of @ref Sn_SR.
+ */
+#define getSn_SSR(sn) \
+ ((uint8_t)WIZCHIP_READ(Sn_SR(sn)))
+#define getSn_SR(sn) getSn_SSR(sn) ///< For compatible ioLibrary. Refer to getSn_SSR().
+
+/**
+ * @ingroup Socket_register_access_function_W5300
+ * @brief Set @ref Sn_PORTR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @param (uint16_t)port Variable to set @ref Sn_PORTR.
+ * @sa getSn_PORTR()
+ */
+#define setSn_PORTR(sn, port) \
+ WIZCHIP_WRITE(Sn_PORTR(sn), port)
+#define setSn_PORT(sn, port) setSn_PORTR(sn, port) ///< For compatible ioLibrary
+
+/**
+ * @ingroup Socket_register_access_function_W5300
+ * @brief Get @ref Sn_PORTR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @return uint16_t. Variable of @ref Sn_PORTR.
+ * @sa setSn_PORTR()
+ */
+#define getSn_PORTR(sn, port) \
+ WIZCHIP_READ(Sn_PORTR(sn))
+#define getSn_PORT(sn) getSn_PORTR(sn) ///< For compatible ioLibrary
+
+/**
+ * @ingroup Socket_register_access_function_W5300
+ * @brief Set @ref Sn_DHAR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @param (uint8_t*)dhar Pointer variable to set socket n destination hardware address. It should be allocated 6 bytes.
+ * @sa getSn_DHAR()
+ */
+#define setSn_DHAR(sn, dhar) { \
+ WIZCHIP_WRITE(Sn_DHAR(sn), (((uint16_t)((dhar)[0])) << 8) + (((uint16_t)((dhar)[1])) & 0x00FF)); \
+ WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_DHAR(sn),2), (((uint16_t)((dhar)[0])) << 8) + (((uint16_t)((dhar)[1])) & 0x00FF)); \
+ WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_DHAR(sn),4), (((uint16_t)((dhar)[0])) << 8) + (((uint16_t)((dhar)[1])) & 0x00FF)); \
+ }
+
+/**
+ * @ingroup Socket_register_access_function_W5300
+ * @brief Get @ref Sn_MR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @param (uint8_t*)dhar Pointer variable to get socket n destination hardware address. It should be allocated 6 bytes.
+ * @sa setSn_DHAR()
+ */
+#define getSn_DHAR(sn, dhar) { \
+ (dhar)[0] = (uint8_t)(WIZCHIP_READ(Sn_DHAR(sn)) >> 8); \
+ (dhar)[1] = (uint8_t) WIZCHIP_READ(Sn_DHAR(sn)); \
+ (dhar)[2] = (uint8_t)(WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_DHAR(sn),2)) >> 8); \
+ (dhar)[3] = (uint8_t) WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_DHAR(sn),2)); \
+ (dhar)[4] = (uint8_t)(WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_DHAR(sn),4)) >> 8); \
+ (dhar)[5] = (uint8_t) WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_DHAR(sn),4)); \
+ }
+
+/**
+ * @ingroup Socket_register_access_function_W5300
+ * @brief Set @ref Sn_DPORT register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @param (uint16_t)dport Value to set @ref Sn_DPORT
+ * @sa getSn_DPORT()
+ */
+#define setSn_DPORTR(sn, dport) \
+ WIZCHIP_WRITE(Sn_DPORTR(sn),dport)
+#define setSn_DPORT(sn, dport) setSn_DPORTR(sn,dport) ///< For compatible ioLibrary. Refer to @ref Sn_DPORTR.
+
+
+/**
+ * @ingroup Socket_register_access_function_W5300
+ * @brief Get @ref Sn_DPORT register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @return uint16_t. Value of @ref Sn_DPORT.
+ * @sa setSn_DPORT()
+ * @note This function is not available because W5300 have a bug to read @ref Sn_DPORTR. \n
+ * Don't use this function.
+ */
+#define getSn_DPORTR(sn) \
+ WIZCHIP_READ(Sn_DPORTR(sn))
+#define getSn_DPORT(sn) getSn_DPORTR(sn) ///< For compatible ioLibrary. Refer to @ref Sn_DPORTR.
+
+/**
+ * @ingroup Socket_register_access_function_W5300
+ * @brief Set @ref Sn_DIPR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @param (uint8_t*)dipr Pointer variable to set socket n destination IP address. It should be allocated 4 bytes.
+ * @sa getSn_DIPR()
+ */
+#define setSn_DIPR(sn, dipr) { \
+ WIZCHIP_WRITE(Sn_DIPR(sn), (((uint16_t)((dipr)[0])) << 8) + (((uint16_t)((dipr)[1])) & 0x00FF)); \
+ WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_DIPR(sn),2), (((uint16_t)((dipr)[2])) << 8) + (((uint16_t)((dipr)[3])) & 0x00FF)); \
+ }
+
+/**
+ * @ingroup Socket_register_access_function_W5300
+ * @brief Get @ref Sn_DIPR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @param (uint8_t*)dipr Pointer variable to get socket n destination IP address. It should be allocated 4 bytes.
+ * @sa setSn_DIPR()
+ */
+#define getSn_DIPR(sn, dipr) { \
+ (dipr)[0] = (uint8_t)(WIZCHIP_READ(Sn_DIPR(sn)) >> 8); \
+ (dipr)[1] = (uint8_t) WIZCHIP_READ(Sn_DIPR(sn)); \
+ (dipr)[2] = (uint8_t)(WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_DIPR(sn),2)) >> 8); \
+ (dipr)[3] = (uint8_t) WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_DIPR(sn),2)); \
+ }
+
+/**
+ * @ingroup Socket_register_access_function_W5300
+ * @brief Set @ref Sn_MSSR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @param (uint16_t)mss Value to set @ref Sn_MSSR
+ * @sa setSn_MSSR()
+ */
+#define setSn_MSSR(sn, mss) \
+ WIZCHIP_WRITE(Sn_MSSR(sn), mss)
+
+/**
+ * @ingroup Socket_register_access_function_W5300
+ * @brief Get @ref Sn_MSSR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @return uint16_t. Value of @ref Sn_MSSR.
+ * @sa setSn_MSSR()
+ */
+#define getSn_MSSR(sn) \
+ WIZCHIP_READ(Sn_MSSR(sn))
+
+/**
+ * @ingroup Socket_register_access_function_W5300
+ * @brief Set @ref Sn_KPALVTR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @param (uint8_t)kpalvt Value to set @ref Sn_KPALVTR
+ * @sa getSn_KPALVTR()
+ */
+#define setSn_KPALVTR(sn, kpalvt) \
+ WIZCHIP_WRITE(Sn_KPALVTR(sn), (WIZCHIP_READ(Sn_KPALVTR(sn)) & 0x00FF) | (((uint16_t)kpalvt)<<8))
+
+/**
+ * @ingroup Socket_register_access_function_W5300
+ * @brief Get @ref Sn_KPALVTR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @return uint8_t. Value of @ref Sn_KPALVTR.
+ * @sa setSn_KPALVTR()
+ */
+#define getSn_KPALVTR(sn) \
+ ((uint8_t)(WIZCHIP_READ(Sn_KPALVTR(sn)) >> 8))
+
+/**
+ * @ingroup Socket_register_access_function_W5300
+ * @brief Set @ref Sn_PROTOR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param (uint8_t)proto Value to set \ref Sn_PROTOR
+ * @sa getSn_PROTOR()
+ */
+#define setSn_PROTOR(sn, proto) \
+ WIZCHIP_WRITE(Sn_PROTOR(sn),(WIZCHIP_READ(Sn_PROTOR(sn) & 0xFF00) | (((uint16_t)proto) & 0x00FF))
+#define setSn_PROTO(sn,proto) setSn_PROTOR(sn,proto) ///< For compatible ioLibrary
+
+/**
+ * @ingroup Socket_register_access_function_W5300
+ * @brief Get @ref Sn_PROTOR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return uint8_t. Value of @ref Sn_PROTOR.
+ * @sa setSn_PROTOR()
+ */
+#define getSn_PROTOR(sn) \
+ ((uint8_t)WIZCHIP_READ(Sn_PROTOR(sn)))
+#define getSn_PROTO(sn) getSn_PROTOR(sn) ///< For compatible ioLibrary
+
+/**
+ * @ingroup Socket_register_access_function_W5300
+ * @brief Set @ref Sn_TX_WRSR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @param (uint32_t)txwrs Value to set @ref Sn_KPALVTR (It should be <= 0x00010000)
+ * @sa getSn_TX_WRSR()
+ */
+#define setSn_TX_WRSR(sn, txwrs) { \
+ WIZCHIP_WRITE(Sn_TX_WRSR(sn), (uint16_t)(((uint32_t)txwrs) >> 16)); \
+ WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_TX_WRSR(sn),2), (uint16_t)txwrs); \
+ }
+
+/**
+ * @ingroup Socket_register_access_function_W5300
+ * @brief Get @ref Sn_TX_WRSR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @return uint32_t. Value of Sn_TX_WRSR.
+ * @sa setSn_TX_WRSR()
+ */
+#define getSn_TX_WRSR(sn) \
+ ( (((uint32_t)WIZCHIP_READ(Sn_TX_WRSR(sn))) << 16) + (((uint32_t)WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_WRSR(sn),1))) & 0x0000FFFF) )
+
+/**
+ * @ingroup Socket_register_access_function_W5300
+ * @brief Get @ref Sn_TX_FSR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @return uint32_t. Value of @ref Sn_TX_FSR.
+ */
+uint32_t getSn_TX_FSR(uint8_t sn);
+
+/**
+ * @ingroup Socket_register_access_function_W5300
+ * @brief Get @ref Sn_RX_RSR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @return uint32_t. Value of @ref Sn_RX_RSR.
+ */
+uint32_t getSn_RX_RSR(uint8_t sn);
+
+/**
+ * @ingroup Socket_register_access_function_W5300
+ * @brief Set @ref Sn_TX_FIFOR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @param (uint16_t)txfifo. Value to set @ref Sn_TX_FIFOR.
+ */
+#define setSn_TX_FIFOR(sn, txfifo) \
+ WIZCHIP_WRITE(Sn_TX_FIFOR(sn), txfifo);
+
+/**
+ * @ingroup Socket_register_access_function_W5300
+ * @brief Get @ref Sn_RX_FIFOR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @return uint16_t. Value of @ref Sn_RX_FIFOR.
+ */
+#define getSn_RX_FIFOR(sn) \
+ WIZCHIP_READ(Sn_RX_FIFOR(sn));
+
+/**
+ * @ingroup Socket_register_access_function_W5300
+ * @brief Set @ref Sn_TOSR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param (uint8_t)tos Value to set @ref Sn_TOSR
+ * @sa getSn_TOSR()
+ */
+#define setSn_TOSR(sn, tos) \
+ WIZCHIP_WRITE(Sn_TOS(sn), ((uint16_t)tos) & 0x00FF)
+#define setSn_TOS(sn,tos) setSn_TOSR(sn,tos) ///< For compatible ioLibrar
+
+/**
+ * @ingroup Socket_register_access_function_W5300
+ * @brief Get @ref Sn_TOSR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_ .
+ * @return uint8_t. Value of Sn_TOSR.
+ * @sa setSn_TOSR()
+ */
+#define getSn_TOSR(sn) \
+ ((uint8_t)WIZCHIP_READ(Sn_TOSR(sn)))
+#define getSn_TOS(sn) getSn_TOSR(sn) ///< For compatible ioLibrar
+
+/**
+ * @ingroup Socket_register_access_function_W5300
+ * @brief Set @ref Sn_TTLR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @param (uint8_t)ttl Value to set @ref Sn_TTLR
+ * @sa getSn_TTLR()
+ */
+#define setSn_TTLR(sn, ttl) \
+ WIZCHIP_WRITE(Sn_TTLR(sn), ((uint16_t)ttl) & 0x00FF)
+#define setSn_TTL(sn,ttl) setSn_TTLR(sn,ttl) ///< For compatible ioLibrary
+
+/**
+ * @ingroup Socket_register_access_function_W5300
+ * @brief Get @ref Sn_TTLR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @return uint8_t. Value of @ref Sn_TTLR.
+ * @sa setSn_TTLR()
+ */
+#define getSn_TTLR(sn) \
+ ((uint8_t)WIZCHIP_READ(Sn_TTL(sn)))
+#define getSn_TTL(sn) getSn_TTLR(sn) ///< For compatible ioLibrary
+
+/**
+ * @ingroup Socket_register_access_function_W5300
+ * @brief Set @ref Sn_FRAGR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @param (uint16_t)frag Value to set @ref Sn_FRAGR
+ * @sa getSn_FRAGR()
+ */
+#define setSn_FRAGR(sn, frag) \
+ WIZCHIP_WRITE(Sn_FRAGR(sn), (uint16_t)(frag >>8))
+#define setSn_FRAG(sn,frag) setSn_FRAGR(sn,flag)
+
+/**
+ * @ingroup Socket_register_access_function_W5300
+ * @brief Get @ref Sn_FRAGR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @return uint16_t. Value of @ref Sn_FRAGR.
+ * @sa setSn_FRAGR()
+ */
+#define getSn_FRAGR(sn) \
+ (WIZCHIP_READ(Sn_FRAG(sn)) << 8)
+#define getSn_FRAG(sn) getSn_FRAGR(sn)
+
+
+/////////////////////////////////////
+// Sn_TXBUF & Sn_RXBUF IO function //
+/////////////////////////////////////
+
+/**
+ * @brief Socket_register_access_function_W5300
+ * @brief Gets the max buffer size of socket sn passed as parameter.
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @return uint32_t. Value of Socket n RX max buffer size.
+ */
+#define getSn_RxMAX(sn) \
+ (((uint32_t)getSn_RXBUF_SIZE(sn)) << 10)
+
+/**
+ * @brief Socket_register_access_function_W5300
+ * @brief Gets the max buffer size of socket sn passed as parameters.
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @return uint32_t. Value of Socket n TX max buffer size.
+ */
+#define getSn_TxMAX(sn) \
+ (((uint32_t)getSn_TXBUF_SIZE(sn)) << 10)
+
+/**
+ * @ingroup Basic_IO_function_W5300
+ * @brief It copies data to internal TX memory
+ *
+ * @details This function reads the Tx write pointer register and after that,
+ * it copies the wizdata(pointer buffer) of the length of len(variable) bytes to internal TX memory
+ * and updates the Tx write pointer register.
+ * This function is being called by send() and sendto() function also.
+ *
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @param wizdata Pointer buffer to write data
+ * @param len Data length
+ * @sa wiz_recv_data()
+ */
+void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint32_t len);
+
+/**
+ * @ingroup Basic_IO_function_W5300
+ * @brief It copies data to your buffer from internal RX memory
+ *
+ * @details This function read the Rx read pointer register and after that,
+ * it copies the received data from internal RX memory
+ * to wizdata(pointer variable) of the length of len(variable) bytes.
+ * This function is being called by recv() also.
+ *
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @param wizdata Pointer buffer to read data
+ * @param len Data length
+ * @sa wiz_send_data()
+ */
+void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint32_t len);
+
+/**
+ * @ingroup Basic_IO_function_W5300
+ * @brief It discard the received data in RX memory.
+ * @details It discards the data of the length of len(variable) bytes in internal RX memory.
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @param len Data length
+ */
+void wiz_recv_ignore(uint8_t sn, uint32_t len);
+
+/// \cond DOXY_APPLY_CODE
+#endif
+/// \endcond
+
+#endif // _W5300_H_
diff --git a/Libraries/ioLibrary_Driver/Ethernet/W5500/w5500.c b/Libraries/ioLibrary_Driver/Ethernet/W5500/w5500.c
new file mode 100644
index 0000000..a853054
--- /dev/null
+++ b/Libraries/ioLibrary_Driver/Ethernet/W5500/w5500.c
@@ -0,0 +1,286 @@
+//*****************************************************************************
+//
+//! \file w5500.c
+//! \brief W5500 HAL Interface.
+//! \version 1.0.2
+//! \date 2013/10/21
+//! \par Revision history
+//! <2015/02/05> Notice
+//! The version history is not updated after this point.
+//! Download the latest version directly from GitHub. Please visit the our GitHub repository for ioLibrary.
+//! >> https://github.com/Wiznet/ioLibrary_Driver
+//! <2014/05/01> V1.0.2
+//! 1. Implicit type casting -> Explicit type casting. Refer to M20140501
+//! Fixed the problem on porting into under 32bit MCU
+//! Issued by Mathias ClauBen, wizwiki forum ID Think01 and bobh
+//! Thank for your interesting and serious advices.
+//! <2013/12/20> V1.0.1
+//! 1. Remove warning
+//! 2. WIZCHIP_READ_BUF WIZCHIP_WRITE_BUF in case _WIZCHIP_IO_MODE_SPI_FDM_
+//! for loop optimized(removed). refer to M20131220
+//! <2013/10/21> 1st Release
+//! \author MidnightCow
+//! \copyright
+//!
+//! Copyright (c) 2013, WIZnet Co., LTD.
+//! All rights reserved.
+//!
+//! Redistribution and use in source and binary forms, with or without
+//! modification, are permitted provided that the following conditions
+//! are met:
+//!
+//! * Redistributions of source code must retain the above copyright
+//! notice, this list of conditions and the following disclaimer.
+//! * Redistributions in binary form must reproduce the above copyright
+//! notice, this list of conditions and the following disclaimer in the
+//! documentation and/or other materials provided with the distribution.
+//! * Neither the name of the nor the names of its
+//! contributors may be used to endorse or promote products derived
+//! from this software without specific prior written permission.
+//!
+//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+//! THE POSSIBILITY OF SUCH DAMAGE.
+//
+//*****************************************************************************
+//#include
+#include "../../../ioLibrary_Driver/Ethernet/W5500/w5500.h"
+
+#define _W5500_SPI_VDM_OP_ 0x00
+#define _W5500_SPI_FDM_OP_LEN1_ 0x01
+#define _W5500_SPI_FDM_OP_LEN2_ 0x02
+#define _W5500_SPI_FDM_OP_LEN4_ 0x03
+
+#if (_WIZCHIP_ == 5500)
+////////////////////////////////////////////////////
+
+uint8_t WIZCHIP_READ(uint32_t AddrSel)
+{
+ uint8_t ret;
+
+#if !defined(SPI_DMA)
+ uint8_t spi_data[3];
+#else
+ uint8_t spi_data[4];
+
+#endif
+
+ WIZCHIP_CRITICAL_ENTER();
+ WIZCHIP.CS._select();
+
+ AddrSel |= (_W5500_SPI_READ_ | _W5500_SPI_VDM_OP_);
+ #if !defined (SPI_DMA)
+ if(!WIZCHIP.IF.SPI._read_burst || !WIZCHIP.IF.SPI._write_burst) // byte operation
+ {
+ WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16);
+ WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8);
+ WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0);
+ }
+ else // burst operation
+ {
+ spi_data[0] = (AddrSel & 0x00FF0000) >> 16;
+ spi_data[1] = (AddrSel & 0x0000FF00) >> 8;
+ spi_data[2] = (AddrSel & 0x000000FF) >> 0;
+ WIZCHIP.IF.SPI._write_burst(spi_data, 3);
+ }
+ ret = WIZCHIP.IF.SPI._read_byte();
+ #else
+ spi_data[0] = (AddrSel & 0x00FF0000) >> 16;
+ spi_data[1] = (AddrSel & 0x0000FF00) >> 8;
+ spi_data[2] = (AddrSel & 0x000000FF) >> 0;
+ WIZCHIP.IF.SPI._read_burst(spi_data, 4);
+ ret = spi_data[3];
+ #endif
+
+ WIZCHIP.CS._deselect();
+ WIZCHIP_CRITICAL_EXIT();
+ return ret;
+}
+
+void WIZCHIP_WRITE(uint32_t AddrSel, uint8_t wb )
+{
+ uint8_t spi_data[4];
+
+ WIZCHIP_CRITICAL_ENTER();
+ WIZCHIP.CS._select();
+
+ AddrSel |= (_W5500_SPI_WRITE_ | _W5500_SPI_VDM_OP_);
+
+ #if !defined (SPI_DMA)
+ //if(!WIZCHIP.IF.SPI._read_burst || !WIZCHIP.IF.SPI._write_burst) // byte operation
+ if(!WIZCHIP.IF.SPI._write_burst) // byte operation
+ {
+ WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16);
+ WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8);
+ WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0);
+ WIZCHIP.IF.SPI._write_byte(wb);
+ }
+ #else // burst operation
+ {
+ spi_data[0] = (AddrSel & 0x00FF0000) >> 16;
+ spi_data[1] = (AddrSel & 0x0000FF00) >> 8;
+ spi_data[2] = (AddrSel & 0x000000FF) >> 0;
+ spi_data[3] = wb;
+ WIZCHIP.IF.SPI._write_burst(spi_data, 4);
+ }
+
+ #endif
+
+ WIZCHIP.CS._deselect();
+ WIZCHIP_CRITICAL_EXIT();
+}
+
+void WIZCHIP_READ_BUF (uint32_t AddrSel, uint8_t* pBuf, uint16_t len)
+{
+ uint8_t spi_data[3];
+ uint16_t i;
+
+ WIZCHIP_CRITICAL_ENTER();
+ WIZCHIP.CS._select();
+
+ AddrSel |= (_W5500_SPI_READ_ | _W5500_SPI_VDM_OP_);
+
+ #if !defined (SPI_DMA)
+ if(!WIZCHIP.IF.SPI._read_burst || !WIZCHIP.IF.SPI._write_burst) // byte operation
+ {
+ WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16);
+ WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8);
+ WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0);
+ for(i = 0; i < len; i++)
+ pBuf[i] = WIZCHIP.IF.SPI._read_byte();
+ }
+ #else
+ // burst operation
+ {
+ spi_data[0] = (AddrSel & 0x00FF0000) >> 16;
+ spi_data[1] = (AddrSel & 0x0000FF00) >> 8;
+ spi_data[2] = (AddrSel & 0x000000FF) >> 0;
+ WIZCHIP.IF.SPI._write_burst(spi_data, 3);
+ WIZCHIP.IF.SPI._read_burst(pBuf, len);
+ }
+ #endif
+
+ WIZCHIP.CS._deselect();
+ WIZCHIP_CRITICAL_EXIT();
+}
+
+void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len)
+{
+ uint8_t spi_data[3];
+ uint16_t i;
+
+ WIZCHIP_CRITICAL_ENTER();
+ WIZCHIP.CS._select();
+
+ AddrSel |= (_W5500_SPI_WRITE_ | _W5500_SPI_VDM_OP_);
+ #if !defined (SPI_DMA)
+ if(!WIZCHIP.IF.SPI._write_burst) // byte operation
+ {
+ WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16);
+ WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8);
+ WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0);
+ for(i = 0; i < len; i++)
+ WIZCHIP.IF.SPI._write_byte(pBuf[i]);
+ }
+ #else // burst operation
+ {
+ spi_data[0] = (AddrSel & 0x00FF0000) >> 16;
+ spi_data[1] = (AddrSel & 0x0000FF00) >> 8;
+ spi_data[2] = (AddrSel & 0x000000FF) >> 0;
+ WIZCHIP.IF.SPI._write_burst(spi_data, 3);
+ WIZCHIP.IF.SPI._write_burst(pBuf, len);
+ }
+ #endif
+ WIZCHIP.CS._deselect();
+ WIZCHIP_CRITICAL_EXIT();
+}
+
+
+uint16_t getSn_TX_FSR(uint8_t sn)
+{
+ uint16_t val=0,val1=0;
+
+ do
+ {
+ val1 = WIZCHIP_READ(Sn_TX_FSR(sn));
+ val1 = (val1 << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn),1));
+ if (val1 != 0)
+ {
+ val = WIZCHIP_READ(Sn_TX_FSR(sn));
+ val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn),1));
+ }
+ }while (val != val1);
+ return val;
+}
+
+
+uint16_t getSn_RX_RSR(uint8_t sn)
+{
+ uint16_t val=0,val1=0;
+
+ do
+ {
+ val1 = WIZCHIP_READ(Sn_RX_RSR(sn));
+ val1 = (val1 << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn),1));
+ if (val1 != 0)
+ {
+ val = WIZCHIP_READ(Sn_RX_RSR(sn));
+ val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn),1));
+ }
+ }while (val != val1);
+ return val;
+}
+
+void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint16_t len)
+{
+ uint16_t ptr = 0;
+ uint32_t addrsel = 0;
+
+ if(len == 0) return;
+ ptr = getSn_TX_WR(sn);
+ //M20140501 : implict type casting -> explict type casting
+ //addrsel = (ptr << 8) + (WIZCHIP_TXBUF_BLOCK(sn) << 3);
+ addrsel = ((uint32_t)ptr << 8) + (WIZCHIP_TXBUF_BLOCK(sn) << 3);
+ //
+ WIZCHIP_WRITE_BUF(addrsel,wizdata, len);
+
+ ptr += len;
+ setSn_TX_WR(sn,ptr);
+}
+
+void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len)
+{
+ uint16_t ptr = 0;
+ uint32_t addrsel = 0;
+
+ if(len == 0) return;
+ ptr = getSn_RX_RD(sn);
+ //M20140501 : implict type casting -> explict type casting
+ //addrsel = ((ptr << 8) + (WIZCHIP_RXBUF_BLOCK(sn) << 3);
+ addrsel = ((uint32_t)ptr << 8) + (WIZCHIP_RXBUF_BLOCK(sn) << 3);
+ //
+ WIZCHIP_READ_BUF(addrsel, wizdata, len);
+ ptr += len;
+
+ setSn_RX_RD(sn,ptr);
+}
+
+
+void wiz_recv_ignore(uint8_t sn, uint16_t len)
+{
+ uint16_t ptr = 0;
+
+ ptr = getSn_RX_RD(sn);
+ ptr += len;
+ setSn_RX_RD(sn,ptr);
+}
+
+#endif
diff --git a/Libraries/ioLibrary_Driver/Ethernet/W5500/w5500.h b/Libraries/ioLibrary_Driver/Ethernet/W5500/w5500.h
new file mode 100644
index 0000000..52b8516
--- /dev/null
+++ b/Libraries/ioLibrary_Driver/Ethernet/W5500/w5500.h
@@ -0,0 +1,2158 @@
+//*****************************************************************************
+//
+//! \file w5500.h
+//! \brief W5500 HAL Header File.
+//! \version 1.0.0
+//! \date 2013/10/21
+//! \par Revision history
+//! <2015/02/05> Notice
+//! The version history is not updated after this point.
+//! Download the latest version directly from GitHub. Please visit the our GitHub repository for ioLibrary.
+//! >> https://github.com/Wiznet/ioLibrary_Driver
+//! <2013/10/21> 1st Release
+//! \author MidnightCow
+//! \copyright
+//!
+//! Copyright (c) 2013, WIZnet Co., LTD.
+//! All rights reserved.
+//!
+//! Redistribution and use in source and binary forms, with or without
+//! modification, are permitted provided that the following conditions
+//! are met:
+//!
+//! * Redistributions of source code must retain the above copyright
+//! notice, this list of conditions and the following disclaimer.
+//! * Redistributions in binary form must reproduce the above copyright
+//! notice, this list of conditions and the following disclaimer in the
+//! documentation and/or other materials provided with the distribution.
+//! * Neither the name of the nor the names of its
+//! contributors may be used to endorse or promote products derived
+//! from this software without specific prior written permission.
+//!
+//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+//! THE POSSIBILITY OF SUCH DAMAGE.
+//
+//*****************************************************************************
+
+//
+
+#ifndef _W5500_H_
+#define _W5500_H_
+
+#include
+#include "wizchip_conf.h"
+
+/// @cond DOXY_APPLY_CODE
+#if (_WIZCHIP_ == 5500)
+/// @endcond
+
+#define _W5500_IO_BASE_ 0x00000000
+
+#define _W5500_SPI_READ_ (0x00 << 2) //< SPI interface Read operation in Control Phase
+#define _W5500_SPI_WRITE_ (0x01 << 2) //< SPI interface Write operation in Control Phase
+
+#define WIZCHIP_CREG_BLOCK 0x00 //< Common register block
+#define WIZCHIP_SREG_BLOCK(N) (1+4*N) //< Socket N register block
+#define WIZCHIP_TXBUF_BLOCK(N) (2+4*N) //< Socket N Tx buffer address block
+#define WIZCHIP_RXBUF_BLOCK(N) (3+4*N) //< Socket N Rx buffer address block
+
+#define WIZCHIP_OFFSET_INC(ADDR, N) (ADDR + (N<<8)) //< Increase offset address
+
+
+///////////////////////////////////////
+// Definition For Legacy Chip Driver //
+///////////////////////////////////////
+#define IINCHIP_READ(ADDR) WIZCHIP_READ(ADDR) ///< The defined for legacy chip driver
+#define IINCHIP_WRITE(ADDR,VAL) WIZCHIP_WRITE(ADDR,VAL) ///< The defined for legacy chip driver
+#define IINCHIP_READ_BUF(ADDR,BUF,LEN) WIZCHIP_READ_BUF(ADDR,BUF,LEN) ///< The defined for legacy chip driver
+#define IINCHIP_WRITE_BUF(ADDR,BUF,LEN) WIZCHIP_WRITE(ADDR,BUF,LEN) ///< The defined for legacy chip driver
+
+//////////////////////////////
+//-------------------------- defgroup ---------------------------------
+/**
+ * @defgroup W5500 W5500
+ *
+ * @brief WHIZCHIP register defines and I/O functions of @b W5500.
+ *
+ * - @ref WIZCHIP_register : @ref Common_register_group and @ref Socket_register_group
+ * - @ref WIZCHIP_IO_Functions : @ref Basic_IO_function, @ref Common_register_access_function and @ref Socket_register_access_function
+ */
+
+
+/**
+ * @defgroup WIZCHIP_register WIZCHIP register
+ * @ingroup W5500
+ *
+ * @brief WHIZCHIP register defines register group of @b W5500.
+ *
+ * - @ref Common_register_group : Common register group
+ * - @ref Socket_register_group : \c SOCKET n register group
+ */
+
+
+/**
+ * @defgroup WIZCHIP_IO_Functions WIZCHIP I/O functions
+ * @ingroup W5500
+ *
+ * @brief This supports the basic I/O functions for @ref WIZCHIP_register.
+ *
+ * - Basic I/O function \n
+ * WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF() \n\n
+ *
+ * - @ref Common_register_group access functions \n
+ * -# @b Mode \n
+ * getMR(), setMR()
+ * -# @b Interrupt \n
+ * getIR(), setIR(), getIMR(), setIMR(), getSIR(), setSIR(), getSIMR(), setSIMR(), getINTLEVEL(), setINTLEVEL()
+ * -# Network Information \n
+ * getSHAR(), setSHAR(), getGAR(), setGAR(), getSUBR(), setSUBR(), getSIPR(), setSIPR()
+ * -# @b Retransmission \n
+ * getRCR(), setRCR(), getRTR(), setRTR()
+ * -# @b PPPoE \n
+ * getPTIMER(), setPTIMER(), getPMAGIC(), getPMAGIC(), getPSID(), setPSID(), getPHAR(), setPHAR(), getPMRU(), setPMRU()
+ * -# ICMP packet \n
+ * getUIPR(), getUPORTR()
+ * -# @b etc. \n
+ * getPHYCFGR(), setPHYCFGR(), getVERSIONR() \n\n
+ *
+ * - \ref Socket_register_group access functions \n
+ * -# SOCKET control \n
+ * getSn_MR(), setSn_MR(), getSn_CR(), setSn_CR(), getSn_IMR(), setSn_IMR(), getSn_IR(), setSn_IR()
+ * -# SOCKET information \n
+ * getSn_SR(), getSn_DHAR(), setSn_DHAR(), getSn_PORT(), setSn_PORT(), getSn_DIPR(), setSn_DIPR(), getSn_DPORT(), setSn_DPORT()
+ * getSn_MSSR(), setSn_MSSR()
+ * -# SOCKET communication \n
+ * getSn_RXBUF_SIZE(), setSn_RXBUF_SIZE(), getSn_TXBUF_SIZE(), setSn_TXBUF_SIZE() \n
+ * getSn_TX_RD(), getSn_TX_WR(), setSn_TX_WR() \n
+ * getSn_RX_RD(), setSn_RX_RD(), getSn_RX_WR() \n
+ * getSn_TX_FSR(), getSn_RX_RSR(), getSn_KPALVTR(), setSn_KPALVTR()
+ * -# IP header field \n
+ * getSn_FRAG(), setSn_FRAG(), getSn_TOS(), setSn_TOS() \n
+ * getSn_TTL(), setSn_TTL()
+ */
+
+
+
+/**
+ * @defgroup Common_register_group Common register
+ * @ingroup WIZCHIP_register
+ *
+ * @brief Common register group\n
+ * It set the basic for the networking\n
+ * It set the configuration such as interrupt, network information, ICMP, etc.
+ * @details
+ * @sa MR : Mode register.
+ * @sa GAR, SUBR, SHAR, SIPR
+ * @sa INTLEVEL, IR, IMR, SIR, SIMR : Interrupt.
+ * @sa _RTR_, _RCR_ : Data retransmission.
+ * @sa PTIMER, PMAGIC, PHAR, PSID, PMRU : PPPoE.
+ * @sa UIPR, UPORTR : ICMP message.
+ * @sa PHYCFGR, VERSIONR : etc.
+ */
+
+
+
+/**
+ * @defgroup Socket_register_group Socket register
+ * @ingroup WIZCHIP_register
+ *
+ * @brief Socket register group.\n
+ * Socket register configures and control SOCKETn which is necessary to data communication.
+ * @details
+ * @sa Sn_MR, Sn_CR, Sn_IR, Sn_IMR : SOCKETn Control
+ * @sa Sn_SR, Sn_PORT, Sn_DHAR, Sn_DIPR, Sn_DPORT : SOCKETn Information
+ * @sa Sn_MSSR, Sn_TOS, Sn_TTL, Sn_KPALVTR, Sn_FRAG : Internet protocol.
+ * @sa Sn_RXBUF_SIZE, Sn_TXBUF_SIZE, Sn_TX_FSR, Sn_TX_RD, Sn_TX_WR, Sn_RX_RSR, Sn_RX_RD, Sn_RX_WR : Data communication
+ */
+
+
+
+ /**
+ * @defgroup Basic_IO_function Basic I/O function
+ * @ingroup WIZCHIP_IO_Functions
+ * @brief These are basic input/output functions to read values from register or write values to register.
+ */
+
+/**
+ * @defgroup Common_register_access_function Common register access functions
+ * @ingroup WIZCHIP_IO_Functions
+ * @brief These are functions to access common registers.
+ */
+
+/**
+ * @defgroup Socket_register_access_function Socket register access functions
+ * @ingroup WIZCHIP_IO_Functions
+ * @brief These are functions to access socket registers.
+ */
+
+//------------------------------- defgroup end --------------------------------------------
+//----------------------------- W5500 Common Registers IOMAP -----------------------------
+/**
+ * @ingroup Common_register_group
+ * @brief Mode Register address(R/W)\n
+ * @ref MR is used for S/W reset, ping block mode, PPPoE mode and etc.
+ * @details Each bit of @ref MR defined as follows.
+ *
+ *
7
6
5
4
3
2
1
0
+ *
RST
Reserved
WOL
PB
PPPoE
Reserved
FARP
Reserved
+ *
+ * - \ref MR_RST : Reset
+ * - \ref MR_WOL : Wake on LAN
+ * - \ref MR_PB : Ping block
+ * - \ref MR_PPPOE : PPPoE mode
+ * - \ref MR_FARP : Force ARP mode
+ */
+#define MR (_W5500_IO_BASE_ + (0x0000 << 8) + (WIZCHIP_CREG_BLOCK << 3))
+
+/**
+ * @ingroup Common_register_group
+ * @brief Gateway IP Register address(R/W)
+ * @details @ref GAR configures the default gateway address.
+ */
+#define GAR (_W5500_IO_BASE_ + (0x0001 << 8) + (WIZCHIP_CREG_BLOCK << 3))
+
+/**
+ * @ingroup Common_register_group
+ * @brief Subnet mask Register address(R/W)
+ * @details @ref SUBR configures the subnet mask address.
+ */
+#define SUBR (_W5500_IO_BASE_ + (0x0005 << 8) + (WIZCHIP_CREG_BLOCK << 3))
+
+/**
+ * @ingroup Common_register_group
+ * @brief Source MAC Register address(R/W)
+ * @details @ref SHAR configures the source hardware address.
+ */
+#define SHAR (_W5500_IO_BASE_ + (0x0009 << 8) + (WIZCHIP_CREG_BLOCK << 3))
+
+/**
+ * @ingroup Common_register_group
+ * @brief Source IP Register address(R/W)
+ * @details @ref SIPR configures the source IP address.
+ */
+#define SIPR (_W5500_IO_BASE_ + (0x000F << 8) + (WIZCHIP_CREG_BLOCK << 3))
+
+/**
+ * @ingroup Common_register_group
+ * @brief Set Interrupt low level timer register address(R/W)
+ * @details @ref INTLEVEL configures the Interrupt Assert Time.
+ */
+#define INTLEVEL (_W5500_IO_BASE_ + (0x0013 << 8) + (WIZCHIP_CREG_BLOCK << 3))
+
+/**
+ * @ingroup Common_register_group
+ * @brief Interrupt Register(R/W)
+ * @details @ref IR indicates the interrupt status. Each bit of @ref IR will be still until the bit will be written to by the host.
+ * If @ref IR is not equal to x00 INTn PIN is asserted to low until it is x00\n\n
+ * Each bit of @ref IR defined as follows.
+ *
+ *
7
6
5
4
3
2
1
0
+ *
CONFLICT
UNREACH
PPPoE
MP
Reserved
Reserved
Reserved
Reserved
+ *
+ * - \ref IR_CONFLICT : IP conflict
+ * - \ref IR_UNREACH : Destination unreachable
+ * - \ref IR_PPPoE : PPPoE connection close
+ * - \ref IR_MP : Magic packet
+ */
+#define IR (_W5500_IO_BASE_ + (0x0015 << 8) + (WIZCHIP_CREG_BLOCK << 3))
+
+/**
+ * @ingroup Common_register_group
+ * @brief Interrupt mask register(R/W)
+ * @details @ref _IMR_ is used to mask interrupts. Each bit of @ref _IMR_ corresponds to each bit of @ref IR.
+ * When a bit of @ref _IMR_ is and the corresponding bit of @ref IR is an interrupt will be issued. In other words,
+ * if a bit of @ref _IMR_ is an interrupt will not be issued even if the corresponding bit of @ref IR is \n\n
+ * Each bit of @ref _IMR_ defined as the following.
+ *
+ *
7
6
5
4
3
2
1
0
+ *
IM_IR7
IM_IR6
IM_IR5
IM_IR4
Reserved
Reserved
Reserved
Reserved
+ *
+ * - \ref IM_IR7 : IP Conflict Interrupt Mask
+ * - \ref IM_IR6 : Destination unreachable Interrupt Mask
+ * - \ref IM_IR5 : PPPoE Close Interrupt Mask
+ * - \ref IM_IR4 : Magic Packet Interrupt Mask
+ */
+//M20150401 : Rename SYMBOE ( Re-define error in a compile)
+//#define IMR (_W5500_IO_BASE_ + (0x0016 << 8) + (WIZCHIP_CREG_BLOCK << 3))
+#define _IMR_ (_W5500_IO_BASE_ + (0x0016 << 8) + (WIZCHIP_CREG_BLOCK << 3))
+
+/**
+ * @ingroup Common_register_group
+ * @brief Socket Interrupt Register(R/W)
+ * @details @ref SIR indicates the interrupt status of Socket.\n
+ * Each bit of @ref SIR be still until @ref Sn_IR is cleared by the host.\n
+ * If @ref Sn_IR is not equal to x00 the n-th bit of @ref SIR is and INTn PIN is asserted until @ref SIR is x00 */
+#define SIR (_W5500_IO_BASE_ + (0x0017 << 8) + (WIZCHIP_CREG_BLOCK << 3))
+
+/**
+ * @ingroup Common_register_group
+ * @brief Socket Interrupt Mask Register(R/W)
+ * @details Each bit of @ref SIMR corresponds to each bit of @ref SIR.
+ * When a bit of @ref SIMR is and the corresponding bit of @ref SIR is Interrupt will be issued.
+ * In other words, if a bit of @ref SIMR is an interrupt will be not issued even if the corresponding bit of @ref SIR is
+ */
+#define SIMR (_W5500_IO_BASE_ + (0x0018 << 8) + (WIZCHIP_CREG_BLOCK << 3))
+
+/**
+ * @ingroup Common_register_group
+ * @brief Timeout register address( 1 is 100us )(R/W)
+ * @details @ref _RTR_ configures the retransmission timeout period. The unit of timeout period is 100us and the default of @ref _RTR_ is x07D0.
+ * And so the default timeout period is 200ms(100us X 2000). During the time configured by @ref _RTR_, W5500 waits for the peer response
+ * to the packet that is transmitted by \ref Sn_CR (CONNECT, DISCON, CLOSE, SEND, SEND_MAC, SEND_KEEP command).
+ * If the peer does not respond within the @ref _RTR_ time, W5500 retransmits the packet or issues timeout.
+ */
+//M20150401 : Rename SYMBOE ( Re-define error in a compile)
+//#define RTR (_W5500_IO_BASE_ + (0x0019 << 8) + (WIZCHIP_CREG_BLOCK << 3))
+#define _RTR_ (_W5500_IO_BASE_ + (0x0019 << 8) + (WIZCHIP_CREG_BLOCK << 3))
+
+/**
+ * @ingroup Common_register_group
+ * @brief Retry count register(R/W)
+ * @details @ref _RCR_ configures the number of time of retransmission.
+ * When retransmission occurs as many as ref _RCR_+1 Timeout interrupt is issued (@ref Sn_IR_TIMEOUT = '1').
+ */
+//M20150401 : Rename SYMBOE ( Re-define error in a compile)
+//#define RCR (_W5500_IO_BASE_ + (0x001B << 8) + (WIZCHIP_CREG_BLOCK << 3))
+#define _RCR_ (_W5500_IO_BASE_ + (0x001B << 8) + (WIZCHIP_CREG_BLOCK << 3))
+
+/**
+ * @ingroup Common_register_group
+ * @brief PPP LCP Request Timer register in PPPoE mode(R/W)
+ * @details @ref PTIMER configures the time for sending LCP echo request. The unit of time is 25ms.
+ */
+#define PTIMER (_W5500_IO_BASE_ + (0x001C << 8) + (WIZCHIP_CREG_BLOCK << 3))
+
+/**
+ * @ingroup Common_register_group
+ * @brief PPP LCP Magic number register in PPPoE mode(R/W)
+ * @details @ref PMAGIC configures the 4bytes magic number to be used in LCP negotiation.
+ */
+#define PMAGIC (_W5500_IO_BASE_ + (0x001D << 8) + (WIZCHIP_CREG_BLOCK << 3))
+
+/**
+ * @ingroup Common_register_group
+ * @brief PPP Destination MAC Register address(R/W)
+ * @details @ref PHAR configures the PPPoE server hardware address that is acquired during PPPoE connection process.
+ */
+#define PHAR (_W5500_IO_BASE_ + (0x001E << 8) + (WIZCHIP_CREG_BLOCK << 3))
+
+/**
+ * @ingroup Common_register_group
+ * @brief PPP Session Identification Register(R/W)
+ * @details @ref PSID configures the PPPoE sever session ID acquired during PPPoE connection process.
+ */
+#define PSID (_W5500_IO_BASE_ + (0x0024 << 8) + (WIZCHIP_CREG_BLOCK << 3))
+
+/**
+ * @ingroup Common_register_group
+ * @brief PPP Maximum Segment Size(MSS) register(R/W)
+ * @details @ref PMRU configures the maximum receive unit of PPPoE.
+ */
+#define PMRU (_W5500_IO_BASE_ + (0x0026 << 8) + (WIZCHIP_CREG_BLOCK << 3))
+
+/**
+ * @ingroup Common_register_group
+ * @brief Unreachable IP register address in UDP mode(R)
+ * @details W5500 receives an ICMP packet(Destination port unreachable) when data is sent to a port number
+ * which socket is not open and @ref IR_UNREACH bit of @ref IR becomes and @ref UIPR & @ref UPORTR indicates
+ * the destination IP address & port number respectively.
+ */
+#define UIPR (_W5500_IO_BASE_ + (0x0028 << 8) + (WIZCHIP_CREG_BLOCK << 3))
+
+/**
+ * @ingroup Common_register_group
+ * @brief Unreachable Port register address in UDP mode(R)
+ * @details W5500 receives an ICMP packet(Destination port unreachable) when data is sent to a port number
+ * which socket is not open and @ref IR_UNREACH bit of @ref IR becomes and @ref UIPR & @ref UPORTR
+ * indicates the destination IP address & port number respectively.
+ */
+#define UPORTR (_W5500_IO_BASE_ + (0x002C << 8) + (WIZCHIP_CREG_BLOCK << 3))
+
+/**
+ * @ingroup Common_register_group
+ * @brief PHY Status Register(R/W)
+ * @details @ref PHYCFGR configures PHY operation mode and resets PHY. In addition, @ref PHYCFGR indicates the status of PHY such as duplex, Speed, Link.
+ */
+#define PHYCFGR (_W5500_IO_BASE_ + (0x002E << 8) + (WIZCHIP_CREG_BLOCK << 3))
+
+// Reserved (_W5500_IO_BASE_ + (0x002F << 8) + (WIZCHIP_CREG_BLOCK << 3))
+// Reserved (_W5500_IO_BASE_ + (0x0030 << 8) + (WIZCHIP_CREG_BLOCK << 3))
+// Reserved (_W5500_IO_BASE_ + (0x0031 << 8) + (WIZCHIP_CREG_BLOCK << 3))
+// Reserved (_W5500_IO_BASE_ + (0x0032 << 8) + (WIZCHIP_CREG_BLOCK << 3))
+// Reserved (_W5500_IO_BASE_ + (0x0033 << 8) + (WIZCHIP_CREG_BLOCK << 3))
+// Reserved (_W5500_IO_BASE_ + (0x0034 << 8) + (WIZCHIP_CREG_BLOCK << 3))
+// Reserved (_W5500_IO_BASE_ + (0x0035 << 8) + (WIZCHIP_CREG_BLOCK << 3))
+// Reserved (_W5500_IO_BASE_ + (0x0036 << 8) + (WIZCHIP_CREG_BLOCK << 3))
+// Reserved (_W5500_IO_BASE_ + (0x0037 << 8) + (WIZCHIP_CREG_BLOCK << 3))
+// Reserved (_W5500_IO_BASE_ + (0x0038 << 8) + (WIZCHIP_CREG_BLOCK << 3))
+
+/**
+ * @ingroup Common_register_group
+ * @brief chip version register address(R)
+ * @details @ref VERSIONR always indicates the W5500 version as @b 0x04.
+ */
+#define VERSIONR (_W5500_IO_BASE_ + (0x0039 << 8) + (WIZCHIP_CREG_BLOCK << 3))
+
+
+//----------------------------- W5500 Socket Registers IOMAP -----------------------------
+/**
+ * @ingroup Socket_register_group
+ * @brief socket Mode register(R/W)
+ * @details @ref Sn_MR configures the option or protocol type of Socket n.\n\n
+ * Each bit of @ref Sn_MR defined as the following.
+ *
+ *
7
6
5
4
3
2
1
0
+ *
MULTI/MFEN
BCASTB
ND/MC/MMB
UCASTB/MIP6B
Protocol[3]
Protocol[2]
Protocol[1]
Protocol[0]
+ *
+ * - @ref Sn_MR_MULTI : Support UDP Multicasting
+ * - @ref Sn_MR_BCASTB : Broadcast block in UDP Multicasting
+ * - @ref Sn_MR_ND : No Delayed Ack(TCP) flag
+ * - @ref Sn_MR_MC : IGMP version used in UDP mulitcasting
+ * - @ref Sn_MR_MMB : Multicast Blocking in @ref Sn_MR_MACRAW mode
+ * - @ref Sn_MR_UCASTB : Unicast Block in UDP Multicating
+ * - @ref Sn_MR_MIP6B : IPv6 packet Blocking in @ref Sn_MR_MACRAW mode
+ * - Protocol
+ *
+ *
Protocol[3]
Protocol[2]
Protocol[1]
Protocol[0]
@b Meaning
+ *
0
0
0
0
Closed
+ *
0
0
0
1
TCP
+ *
0
0
1
0
UDP
+ *
0
1
0
0
MACRAW
+ *
+ * - @ref Sn_MR_MACRAW : MAC LAYER RAW SOCK \n
+ * - @ref Sn_MR_UDP : UDP
+ * - @ref Sn_MR_TCP : TCP
+ * - @ref Sn_MR_CLOSE : Unused socket
+ * @note MACRAW mode should be only used in Socket 0.
+ */
+#define Sn_MR(N) (_W5500_IO_BASE_ + (0x0000 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
+
+/**
+ * @ingroup Socket_register_group
+ * @brief Socket command register(R/W)
+ * @details This is used to set the command for Socket n such as OPEN, CLOSE, CONNECT, LISTEN, SEND, and RECEIVE.\n
+ * After W5500 accepts the command, the @ref Sn_CR register is automatically cleared to 0x00.
+ * Even though @ref Sn_CR is cleared to 0x00, the command is still being processed.\n
+ * To check whether the command is completed or not, please check the @ref Sn_IR or @ref Sn_SR.
+ * - @ref Sn_CR_OPEN : Initialize or open socket.
+ * - @ref Sn_CR_LISTEN : Wait connection request in TCP mode(Server mode)
+ * - @ref Sn_CR_CONNECT : Send connection request in TCP mode(Client mode)
+ * - @ref Sn_CR_DISCON : Send closing request in TCP mode.
+ * - @ref Sn_CR_CLOSE : Close socket.
+ * - @ref Sn_CR_SEND : Update TX buffer pointer and send data.
+ * - @ref Sn_CR_SEND_MAC : Send data with MAC address, so without ARP process.
+ * - @ref Sn_CR_SEND_KEEP : Send keep alive message.
+ * - @ref Sn_CR_RECV : Update RX buffer pointer and receive data.
+ */
+#define Sn_CR(N) (_W5500_IO_BASE_ + (0x0001 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
+
+/**
+ * @ingroup Socket_register_group
+ * @brief Socket interrupt register(R)
+ * @details @ref Sn_IR indicates the status of Socket Interrupt such as establishment, termination, receiving data, timeout).\n
+ * When an interrupt occurs and the corresponding bit of @ref Sn_IMR is the corresponding bit of @ref Sn_IR becomes \n
+ * In order to clear the @ref Sn_IR bit, the host should write the bit to \n
+ *
+ *
7
6
5
4
3
2
1
0
+ *
Reserved
Reserved
Reserved
SEND_OK
TIMEOUT
RECV
DISCON
CON
+ *
+ * - \ref Sn_IR_SENDOK : SEND_OK Interrupt
+ * - \ref Sn_IR_TIMEOUT : TIMEOUT Interrupt
+ * - \ref Sn_IR_RECV : RECV Interrupt
+ * - \ref Sn_IR_DISCON : DISCON Interrupt
+ * - \ref Sn_IR_CON : CON Interrupt
+ */
+#define Sn_IR(N) (_W5500_IO_BASE_ + (0x0002 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
+
+/**
+ * @ingroup Socket_register_group
+ * @brief Socket status register(R)
+ * @details @ref Sn_SR indicates the status of Socket n.\n
+ * The status of Socket n is changed by @ref Sn_CR or some special control packet as SYN, FIN packet in TCP.
+ * @par Normal status
+ * - @ref SOCK_CLOSED : Closed
+ * - @ref SOCK_INIT : Initiate state
+ * - @ref SOCK_LISTEN : Listen state
+ * - @ref SOCK_ESTABLISHED : Success to connect
+ * - @ref SOCK_CLOSE_WAIT : Closing state
+ * - @ref SOCK_UDP : UDP socket
+ * - @ref SOCK_MACRAW : MAC raw mode socket
+ *@par Temporary status during changing the status of Socket n.
+ * - @ref SOCK_SYNSENT : This indicates Socket n sent the connect-request packet (SYN packet) to a peer.
+ * - @ref SOCK_SYNRECV : It indicates Socket n successfully received the connect-request packet (SYN packet) from a peer.
+ * - @ref SOCK_FIN_WAIT : Connection state
+ * - @ref SOCK_CLOSING : Closing state
+ * - @ref SOCK_TIME_WAIT : Closing state
+ * - @ref SOCK_LAST_ACK : Closing state
+ */
+#define Sn_SR(N) (_W5500_IO_BASE_ + (0x0003 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
+
+/**
+ * @ingroup Socket_register_group
+ * @brief source port register(R/W)
+ * @details @ref Sn_PORT configures the source port number of Socket n.
+ * It is valid when Socket n is used in TCP/UDP mode. It should be set before OPEN command is ordered.
+ */
+#define Sn_PORT(N) (_W5500_IO_BASE_ + (0x0004 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
+
+/**
+ * @ingroup Socket_register_group
+ * @brief Peer MAC register address(R/W)
+ * @details @ref Sn_DHAR configures the destination hardware address of Socket n when using SEND_MAC command in UDP mode or
+ * it indicates that it is acquired in ARP-process by CONNECT/SEND command.
+ */
+#define Sn_DHAR(N) (_W5500_IO_BASE_ + (0x0006 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
+
+/**
+ * @ingroup Socket_register_group
+ * @brief Peer IP register address(R/W)
+ * @details @ref Sn_DIPR configures or indicates the destination IP address of Socket n. It is valid when Socket n is used in TCP/UDP mode.
+ * In TCP client mode, it configures an IP address of TCP serverbefore CONNECT command.
+ * In TCP server mode, it indicates an IP address of TCP clientafter successfully establishing connection.
+ * In UDP mode, it configures an IP address of peer to be received the UDP packet by SEND or SEND_MAC command.
+ */
+#define Sn_DIPR(N) (_W5500_IO_BASE_ + (0x000C << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
+
+/**
+ * @ingroup Socket_register_group
+ * @brief Peer port register address(R/W)
+ * @details @ref Sn_DPORT configures or indicates the destination port number of Socket n. It is valid when Socket n is used in TCP/UDP mode.
+ * In TCP clientmode, it configures the listen port number of TCP serverbefore CONNECT command.
+ * In TCP Servermode, it indicates the port number of TCP client after successfully establishing connection.
+ * In UDP mode, it configures the port number of peer to be transmitted the UDP packet by SEND/SEND_MAC command.
+ */
+#define Sn_DPORT(N) (_W5500_IO_BASE_ + (0x0010 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
+
+/**
+ * @ingroup Socket_register_group
+ * @brief Maximum Segment Size(Sn_MSSR0) register address(R/W)
+ * @details @ref Sn_MSSR configures or indicates the MTU(Maximum Transfer Unit) of Socket n.
+ */
+#define Sn_MSSR(N) (_W5500_IO_BASE_ + (0x0012 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
+
+// Reserved (_W5500_IO_BASE_ + (0x0014 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
+
+/**
+ * @ingroup Socket_register_group
+ * @brief IP Type of Service(TOS) Register(R/W)
+ * @details @ref Sn_TOS configures the TOS(Type Of Service field in IP Header) of Socket n.
+ * It is set before OPEN command.
+ */
+#define Sn_TOS(N) (_W5500_IO_BASE_ + (0x0015 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
+/**
+ * @ingroup Socket_register_group
+ * @brief IP Time to live(TTL) Register(R/W)
+ * @details @ref Sn_TTL configures the TTL(Time To Live field in IP header) of Socket n.
+ * It is set before OPEN command.
+ */
+#define Sn_TTL(N) (_W5500_IO_BASE_ + (0x0016 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
+// Reserved (_W5500_IO_BASE_ + (0x0017 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
+// Reserved (_W5500_IO_BASE_ + (0x0018 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
+// Reserved (_W5500_IO_BASE_ + (0x0019 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
+// Reserved (_W5500_IO_BASE_ + (0x001A << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
+// Reserved (_W5500_IO_BASE_ + (0x001B << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
+// Reserved (_W5500_IO_BASE_ + (0x001C << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
+// Reserved (_W5500_IO_BASE_ + (0x001D << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
+
+/**
+ * @ingroup Socket_register_group
+ * @brief Receive memory size register(R/W)
+ * @details @ref Sn_RXBUF_SIZE configures the RX buffer block size of Socket n.
+ * Socket n RX Buffer Block size can be configured with 1,2,4,8, and 16 Kbytes.
+ * If a different size is configured, the data cannot be normally received from a peer.
+ * Although Socket n RX Buffer Block size is initially configured to 2Kbytes,
+ * user can re-configure its size using @ref Sn_RXBUF_SIZE. The total sum of @ref Sn_RXBUF_SIZE can not be exceed 16Kbytes.
+ * When exceeded, the data reception error is occurred.
+ */
+#define Sn_RXBUF_SIZE(N) (_W5500_IO_BASE_ + (0x001E << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
+
+/**
+ * @ingroup Socket_register_group
+ * @brief Transmit memory size register(R/W)
+ * @details @ref Sn_TXBUF_SIZE configures the TX buffer block size of Socket n. Socket n TX Buffer Block size can be configured with 1,2,4,8, and 16 Kbytes.
+ * If a different size is configured, the data can�t be normally transmitted to a peer.
+ * Although Socket n TX Buffer Block size is initially configured to 2Kbytes,
+ * user can be re-configure its size using @ref Sn_TXBUF_SIZE. The total sum of @ref Sn_TXBUF_SIZE can not be exceed 16Kbytes.
+ * When exceeded, the data transmission error is occurred.
+ */
+#define Sn_TXBUF_SIZE(N) (_W5500_IO_BASE_ + (0x001F << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
+
+/**
+ * @ingroup Socket_register_group
+ * @brief Transmit free memory size register(R)
+ * @details @ref Sn_TX_FSR indicates the free size of Socket n TX Buffer Block. It is initialized to the configured size by @ref Sn_TXBUF_SIZE.
+ * Data bigger than @ref Sn_TX_FSR should not be saved in the Socket n TX Buffer because the bigger data overwrites the previous saved data not yet sent.
+ * Therefore, check before saving the data to the Socket n TX Buffer, and if data is equal or smaller than its checked size,
+ * transmit the data with SEND/SEND_MAC command after saving the data in Socket n TX buffer. But, if data is bigger than its checked size,
+ * transmit the data after dividing into the checked size and saving in the Socket n TX buffer.
+ */
+#define Sn_TX_FSR(N) (_W5500_IO_BASE_ + (0x0020 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
+
+/**
+ * @ingroup Socket_register_group
+ * @brief Transmit memory read pointer register address(R)
+ * @details @ref Sn_TX_RD is initialized by OPEN command. However, if Sn_MR(P[3:0]) is TCP mode(001, it is re-initialized while connecting with TCP.
+ * After its initialization, it is auto-increased by SEND command.
+ * SEND command transmits the saved data from the current @ref Sn_TX_RD to the @ref Sn_TX_WR in the Socket n TX Buffer.
+ * After transmitting the saved data, the SEND command increases the @ref Sn_TX_RD as same as the @ref Sn_TX_WR.
+ * If its increment value exceeds the maximum value 0xFFFF, (greater than 0x10000 and the carry bit occurs),
+ * then the carry bit is ignored and will automatically update with the lower 16bits value.
+ */
+#define Sn_TX_RD(N) (_W5500_IO_BASE_ + (0x0022 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
+
+/**
+ * @ingroup Socket_register_group
+ * @brief Transmit memory write pointer register address(R/W)
+ * @details @ref Sn_TX_WR is initialized by OPEN command. However, if Sn_MR(P[3:0]) is TCP mode(001, it is re-initialized while connecting with TCP.\n
+ * It should be read or be updated like as follows.\n
+ * 1. Read the starting address for saving the transmitting data.\n
+ * 2. Save the transmitting data from the starting address of Socket n TX buffer.\n
+ * 3. After saving the transmitting data, update @ref Sn_TX_WR to the increased value as many as transmitting data size.
+ * If the increment value exceeds the maximum value 0xFFFF(greater than 0x10000 and the carry bit occurs),
+ * then the carry bit is ignored and will automatically update with the lower 16bits value.\n
+ * 4. Transmit the saved data in Socket n TX Buffer by using SEND/SEND command
+ */
+#define Sn_TX_WR(N) (_W5500_IO_BASE_ + (0x0024 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
+
+/**
+ * @ingroup Socket_register_group
+ * @brief Received data size register(R)
+ * @details @ref Sn_RX_RSR indicates the data size received and saved in Socket n RX Buffer.
+ * @ref Sn_RX_RSR does not exceed the @ref Sn_RXBUF_SIZE and is calculated as the difference between
+ * �Socket n RX Write Pointer (@ref Sn_RX_WR)and �Socket n RX Read Pointer (@ref Sn_RX_RD)
+ */
+#define Sn_RX_RSR(N) (_W5500_IO_BASE_ + (0x0026 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
+
+/**
+ * @ingroup Socket_register_group
+ * @brief Read point of Receive memory(R/W)
+ * @details @ref Sn_RX_RD is initialized by OPEN command. Make sure to be read or updated as follows.\n
+ * 1. Read the starting save address of the received data.\n
+ * 2. Read data from the starting address of Socket n RX Buffer.\n
+ * 3. After reading the received data, Update @ref Sn_RX_RD to the increased value as many as the reading size.
+ * If the increment value exceeds the maximum value 0xFFFF, that is, is greater than 0x10000 and the carry bit occurs,
+ * update with the lower 16bits value ignored the carry bit.\n
+ * 4. Order RECV command is for notifying the updated @ref Sn_RX_RD to W5500.
+ */
+#define Sn_RX_RD(N) (_W5500_IO_BASE_ + (0x0028 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
+
+/**
+ * @ingroup Socket_register_group
+ * @brief Write point of Receive memory(R)
+ * @details @ref Sn_RX_WR is initialized by OPEN command and it is auto-increased by the data reception.
+ * If the increased value exceeds the maximum value 0xFFFF, (greater than 0x10000 and the carry bit occurs),
+ * then the carry bit is ignored and will automatically update with the lower 16bits value.
+ */
+#define Sn_RX_WR(N) (_W5500_IO_BASE_ + (0x002A << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
+
+/**
+ * @ingroup Socket_register_group
+ * @brief socket interrupt mask register(R)
+ * @details @ref Sn_IMR masks the interrupt of Socket n.
+ * Each bit corresponds to each bit of @ref Sn_IR. When a Socket n Interrupt is occurred and the corresponding bit of @ref Sn_IMR is
+ * the corresponding bit of @ref Sn_IR becomes When both the corresponding bit of @ref Sn_IMR and @ref Sn_IR are and the n-th bit of @ref IR is
+ * Host is interrupted by asserted INTn PIN to low.
+ */
+#define Sn_IMR(N) (_W5500_IO_BASE_ + (0x002C << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
+
+/**
+ * @ingroup Socket_register_group
+ * @brief Fragment field value in IP header register(R/W)
+ * @details @ref Sn_FRAG configures the FRAG(Fragment field in IP header).
+ */
+#define Sn_FRAG(N) (_W5500_IO_BASE_ + (0x002D << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
+
+/**
+ * @ingroup Socket_register_group
+ * @brief Keep Alive Timer register(R/W)
+ * @details @ref Sn_KPALVTR configures the transmitting timer of �KEEP ALIVE(KA)packet of SOCKETn. It is valid only in TCP mode,
+ * and ignored in other modes. The time unit is 5s.
+ * KA packet is transmittable after @ref Sn_SR is changed to SOCK_ESTABLISHED and after the data is transmitted or received to/from a peer at least once.
+ * In case of '@ref Sn_KPALVTR > 0', W5500 automatically transmits KA packet after time-period for checking the TCP connection (Auto-keepalive-process).
+ * In case of '@ref Sn_KPALVTR = 0', Auto-keep-alive-process will not operate,
+ * and KA packet can be transmitted by SEND_KEEP command by the host (Manual-keep-alive-process).
+ * Manual-keep-alive-process is ignored in case of '@ref Sn_KPALVTR > 0'.
+ */
+#define Sn_KPALVTR(N) (_W5500_IO_BASE_ + (0x002F << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
+
+//#define Sn_TSR(N) (_W5500_IO_BASE_ + (0x0030 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
+
+
+//----------------------------- W5500 Register values -----------------------------
+
+/* MODE register values */
+/**
+ * @brief Reset
+ * @details If this bit is All internal registers will be initialized. It will be automatically cleared as after S/W reset.
+ */
+#define MR_RST 0x80
+
+/**
+ * @brief Wake on LAN
+ * @details 0 : Disable WOL mode\n
+ * 1 : Enable WOL mode\n
+ * If WOL mode is enabled and the received magic packet over UDP has been normally processed, the Interrupt PIN (INTn) asserts to low.
+ * When using WOL mode, the UDP Socket should be opened with any source port number. (Refer to Socket n Mode Register (@ref Sn_MR) for opening Socket.)
+ * @note The magic packet over UDP supported by W5500 consists of 6 bytes synchronization stream (xFFFFFFFFFFFF and
+ * 16 times Target MAC address stream in UDP payload. The options such like password are ignored. You can use any UDP source port number for WOL mode.
+ */
+#define MR_WOL 0x20
+
+/**
+ * @brief Ping block
+ * @details 0 : Disable Ping block\n
+ * 1 : Enable Ping block\n
+ * If the bit is it blocks the response to a ping request.
+ */
+#define MR_PB 0x10
+
+/**
+ * @brief Enable PPPoE
+ * @details 0 : DisablePPPoE mode\n
+ * 1 : EnablePPPoE mode\n
+ * If you use ADSL, this bit should be
+ */
+#define MR_PPPOE 0x08
+
+/**
+ * @brief Enable UDP_FORCE_ARP CHECHK
+ * @details 0 : Disable Force ARP mode\n
+ * 1 : Enable Force ARP mode\n
+ * In Force ARP mode, It forces on sending ARP Request whenever data is sent.
+ */
+#define MR_FARP 0x02
+
+/* IR register values */
+/**
+ * @brief Check IP conflict.
+ * @details Bit is set as when own source IP address is same with the sender IP address in the received ARP request.
+ */
+#define IR_CONFLICT 0x80
+
+/**
+ * @brief Get the destination unreachable message in UDP sending.
+ * @details When receiving the ICMP (Destination port unreachable) packet, this bit is set as
+ * When this bit is Destination Information such as IP address and Port number may be checked with the corresponding @ref UIPR & @ref UPORTR.
+ */
+#define IR_UNREACH 0x40
+
+/**
+ * @brief Get the PPPoE close message.
+ * @details When PPPoE is disconnected during PPPoE mode, this bit is set.
+ */
+#define IR_PPPoE 0x20
+
+/**
+ * @brief Get the magic packet interrupt.
+ * @details When WOL mode is enabled and receives the magic packet over UDP, this bit is set.
+ */
+#define IR_MP 0x10
+
+
+/* PHYCFGR register value */
+#define PHYCFGR_RST ~(1<<7) //< For PHY reset, must operate AND mask.
+#define PHYCFGR_OPMD (1<<6) // Configre PHY with OPMDC value
+#define PHYCFGR_OPMDC_ALLA (7<<3)
+#define PHYCFGR_OPMDC_PDOWN (6<<3)
+#define PHYCFGR_OPMDC_NA (5<<3)
+#define PHYCFGR_OPMDC_100FA (4<<3)
+#define PHYCFGR_OPMDC_100F (3<<3)
+#define PHYCFGR_OPMDC_100H (2<<3)
+#define PHYCFGR_OPMDC_10F (1<<3)
+#define PHYCFGR_OPMDC_10H (0<<3)
+#define PHYCFGR_DPX_FULL (1<<2)
+#define PHYCFGR_DPX_HALF (0<<2)
+#define PHYCFGR_SPD_100 (1<<1)
+#define PHYCFGR_SPD_10 (0<<1)
+#define PHYCFGR_LNK_ON (1<<0)
+#define PHYCFGR_LNK_OFF (0<<0)
+
+/* IMR register values */
+/**
+ * @brief IP Conflict Interrupt Mask.
+ * @details 0: Disable IP Conflict Interrupt\n
+ * 1: Enable IP Conflict Interrupt
+ */
+#define IM_IR7 0x80
+
+/**
+ * @brief Destination unreachable Interrupt Mask.
+ * @details 0: Disable Destination unreachable Interrupt\n
+ * 1: Enable Destination unreachable Interrupt
+ */
+#define IM_IR6 0x40
+
+/**
+ * @brief PPPoE Close Interrupt Mask.
+ * @details 0: Disable PPPoE Close Interrupt\n
+ * 1: Enable PPPoE Close Interrupt
+ */
+#define IM_IR5 0x20
+
+/**
+ * @brief Magic Packet Interrupt Mask.
+ * @details 0: Disable Magic Packet Interrupt\n
+ * 1: Enable Magic Packet Interrupt
+ */
+#define IM_IR4 0x10
+
+/* Sn_MR Default values */
+/**
+ * @brief Support UDP Multicasting
+ * @details 0 : disable Multicasting\n
+ * 1 : enable Multicasting\n
+ * This bit is applied only during UDP mode(P[3:0] = 010.\n
+ * To use multicasting, @ref Sn_DIPR & @ref Sn_DPORT should be respectively configured with the multicast group IP address & port number
+ * before Socket n is opened by OPEN command of @ref Sn_CR.
+ */
+#define Sn_MR_MULTI 0x80
+
+/**
+ * @brief Broadcast block in UDP Multicasting.
+ * @details 0 : disable Broadcast Blocking\n
+ * 1 : enable Broadcast Blocking\n
+ * This bit blocks to receive broadcasting packet during UDP mode(P[3:0] = 010.\m
+ * In addition, This bit does when MACRAW mode(P[3:0] = 100
+ */
+#define Sn_MR_BCASTB 0x40
+
+/**
+ * @brief No Delayed Ack(TCP), Multicast flag
+ * @details 0 : Disable No Delayed ACK option\n
+ * 1 : Enable No Delayed ACK option\n
+ * This bit is applied only during TCP mode (P[3:0] = 001.\n
+ * When this bit is It sends the ACK packet without delay as soon as a Data packet is received from a peer.\n
+ * When this bit is It sends the ACK packet after waiting for the timeout time configured by @ref _RTR_.
+ */
+#define Sn_MR_ND 0x20
+
+/**
+ * @brief Unicast Block in UDP Multicasting
+ * @details 0 : disable Unicast Blocking\n
+ * 1 : enable Unicast Blocking\n
+ * This bit blocks receiving the unicast packet during UDP mode(P[3:0] = 010 and MULTI =
+ */
+#define Sn_MR_UCASTB 0x10
+
+/**
+ * @brief MAC LAYER RAW SOCK
+ * @details This configures the protocol mode of Socket n.
+ * @note MACRAW mode should be only used in Socket 0.
+ */
+#define Sn_MR_MACRAW 0x04
+
+#define Sn_MR_IPRAW 0x03 /**< IP LAYER RAW SOCK */
+
+/**
+ * @brief UDP
+ * @details This configures the protocol mode of Socket n.
+ */
+#define Sn_MR_UDP 0x02
+
+/**
+ * @brief TCP
+ * @details This configures the protocol mode of Socket n.
+ */
+#define Sn_MR_TCP 0x01
+
+/**
+ * @brief Unused socket
+ * @details This configures the protocol mode of Socket n.
+ */
+#define Sn_MR_CLOSE 0x00
+
+/* Sn_MR values used with Sn_MR_MACRAW */
+/**
+ * @brief MAC filter enable in @ref Sn_MR_MACRAW mode
+ * @details 0 : disable MAC Filtering\n
+ * 1 : enable MAC Filtering\n
+ * This bit is applied only during MACRAW mode(P[3:0] = 100.\n
+ * When set as W5500 can only receive broadcasting packet or packet sent to itself.
+ * When this bit is W5500 can receive all packets on Ethernet.
+ * If user wants to implement Hybrid TCP/IP stack,
+ * it is recommended that this bit is set as for reducing host overhead to process the all received packets.
+ */
+#define Sn_MR_MFEN Sn_MR_MULTI
+
+/**
+ * @brief Multicast Blocking in @ref Sn_MR_MACRAW mode
+ * @details 0 : using IGMP version 2\n
+ * 1 : using IGMP version 1\n
+ * This bit is applied only during UDP mode(P[3:0] = 010 and MULTI =
+ * It configures the version for IGMP messages (Join/Leave/Report).
+ */
+#define Sn_MR_MMB Sn_MR_ND
+
+/**
+ * @brief IPv6 packet Blocking in @ref Sn_MR_MACRAW mode
+ * @details 0 : disable IPv6 Blocking\n
+ * 1 : enable IPv6 Blocking\n
+ * This bit is applied only during MACRAW mode (P[3:0] = 100. It blocks to receiving the IPv6 packet.
+ */
+#define Sn_MR_MIP6B Sn_MR_UCASTB
+
+/* Sn_MR value used with Sn_MR_UDP & Sn_MR_MULTI */
+/**
+ * @brief IGMP version used in UDP mulitcasting
+ * @details 0 : disable Multicast Blocking\n
+ * 1 : enable Multicast Blocking\n
+ * This bit is applied only when MACRAW mode(P[3:0] = 100. It blocks to receive the packet with multicast MAC address.
+ */
+#define Sn_MR_MC Sn_MR_ND
+
+/* Sn_MR alternate values */
+/**
+ * @brief For Berkeley Socket API
+ */
+#define SOCK_STREAM Sn_MR_TCP
+
+/**
+ * @brief For Berkeley Socket API
+ */
+#define SOCK_DGRAM Sn_MR_UDP
+
+
+/* Sn_CR values */
+/**
+ * @brief Initialize or open socket
+ * @details Socket n is initialized and opened according to the protocol selected in Sn_MR(P3:P0).
+ * The table below shows the value of @ref Sn_SR corresponding to @ref Sn_MR.\n
+ *
+ *
\b Sn_MR (P[3:0])
\b Sn_SR
+ *
Sn_MR_CLOSE (000)
+ *
Sn_MR_TCP (001)
SOCK_INIT (0x13)
+ *
Sn_MR_UDP (010)
SOCK_UDP (0x22)
+ *
S0_MR_MACRAW (100)
SOCK_MACRAW (0x02)
+ *
+ */
+#define Sn_CR_OPEN 0x01
+
+/**
+ * @brief Wait connection request in TCP mode(Server mode)
+ * @details This is valid only in TCP mode (\ref Sn_MR(P3:P0) = \ref Sn_MR_TCP).
+ * In this mode, Socket n operates as a TCP serverand waits for connection-request (SYN packet) from any TCP client
+ * The @ref Sn_SR changes the state from \ref SOCK_INIT to \ref SOCKET_LISTEN.
+ * When a TCP clientconnection request is successfully established,
+ * the @ref Sn_SR changes from SOCK_LISTEN to SOCK_ESTABLISHED and the @ref Sn_IR(0) becomes
+ * But when a TCP clientconnection request is failed, @ref Sn_IR(3) becomes and the status of @ref Sn_SR changes to SOCK_CLOSED.
+ */
+#define Sn_CR_LISTEN 0x02
+
+/**
+ * @brief Send connection request in TCP mode(Client mode)
+ * @details To connect, a connect-request (SYN packet) is sent to TCP serverconfigured by @ref Sn_DIPR & Sn_DPORT(destination address & port).
+ * If the connect-request is successful, the @ref Sn_SR is changed to @ref SOCK_ESTABLISHED and the Sn_IR(0) becomes \n\n
+ * The connect-request fails in the following three cases.\n
+ * 1. When a @b ARPTO occurs (@ref Sn_IR[3] = ) because destination hardware address is not acquired through the ARP-process.\n
+ * 2. When a @b SYN/ACK packet is not received and @b TCPTO (Sn_IR(3) = )\n
+ * 3. When a @b RST packet is received instead of a @b SYN/ACK packet. In these cases, @ref Sn_SR is changed to @ref SOCK_CLOSED.
+ * @note This is valid only in TCP mode and operates when Socket n acts as TCP client
+ */
+#define Sn_CR_CONNECT 0x04
+
+/**
+ * @brief Send closing request in TCP mode
+ * @details Regardless of TCP serveror TCP client the DISCON command processes the disconnect-process (b>Active closeor Passive close.\n
+ * @par Active close
+ * it transmits disconnect-request(FIN packet) to the connected peer\n
+ * @par Passive close
+ * When FIN packet is received from peer, a FIN packet is replied back to the peer.\n
+ * @details When the disconnect-process is successful (that is, FIN/ACK packet is received successfully), @ref Sn_SR is changed to @ref SOCK_CLOSED.\n
+ * Otherwise, TCPTO occurs (\ref Sn_IR(3)='1') and then @ref Sn_SR is changed to @ref SOCK_CLOSED.
+ * @note Valid only in TCP mode.
+ */
+#define Sn_CR_DISCON 0x08
+
+/**
+ * @brief Close socket
+ * @details Sn_SR is changed to @ref SOCK_CLOSED.
+ */
+#define Sn_CR_CLOSE 0x10
+
+/**
+ * @brief Update TX buffer pointer and send data
+ * @details SEND transmits all the data in the Socket n TX buffer.\n
+ * For more details, please refer to Socket n TX Free Size Register (@ref Sn_TX_FSR), Socket n,
+ * TX Write Pointer Register(@ref Sn_TX_WR), and Socket n TX Read Pointer Register(@ref Sn_TX_RD).
+ */
+#define Sn_CR_SEND 0x20
+
+/**
+ * @brief Send data with MAC address, so without ARP process
+ * @details The basic operation is same as SEND.\n
+ * Normally SEND transmits data after destination hardware address is acquired by the automatic ARP-process(Address Resolution Protocol).\n
+ * But SEND_MAC transmits data without the automatic ARP-process.\n
+ * In this case, the destination hardware address is acquired from @ref Sn_DHAR configured by host, instead of APR-process.
+ * @note Valid only in UDP mode.
+ */
+#define Sn_CR_SEND_MAC 0x21
+
+/**
+ * @brief Send keep alive message
+ * @details It checks the connection status by sending 1byte keep-alive packet.\n
+ * If the peer can not respond to the keep-alive packet during timeout time, the connection is terminated and the timeout interrupt will occur.
+ * @note Valid only in TCP mode.
+ */
+#define Sn_CR_SEND_KEEP 0x22
+
+/**
+ * @brief Update RX buffer pointer and receive data
+ * @details RECV completes the processing of the received data in Socket n RX Buffer by using a RX read pointer register (@ref Sn_RX_RD).\n
+ * For more details, refer to Socket n RX Received Size Register (@ref Sn_RX_RSR), Socket n RX Write Pointer Register (@ref Sn_RX_WR),
+ * and Socket n RX Read Pointer Register (@ref Sn_RX_RD).
+ */
+#define Sn_CR_RECV 0x40
+
+/* Sn_IR values */
+/**
+ * @brief SEND_OK Interrupt
+ * @details This is issued when SEND command is completed.
+ */
+#define Sn_IR_SENDOK 0x10
+
+/**
+ * @brief TIMEOUT Interrupt
+ * @details This is issued when ARPTO or TCPTO occurs.
+ */
+#define Sn_IR_TIMEOUT 0x08
+
+/**
+ * @brief RECV Interrupt
+ * @details This is issued whenever data is received from a peer.
+ */
+#define Sn_IR_RECV 0x04
+
+/**
+ * @brief DISCON Interrupt
+ * @details This is issued when FIN or FIN/ACK packet is received from a peer.
+ */
+#define Sn_IR_DISCON 0x02
+
+/**
+ * @brief CON Interrupt
+ * @details This is issued one time when the connection with peer is successful and then @ref Sn_SR is changed to @ref SOCK_ESTABLISHED.
+ */
+#define Sn_IR_CON 0x01
+
+/* Sn_SR values */
+/**
+ * @brief Closed
+ * @details This indicates that Socket n is released.\n
+ * When DICON, CLOSE command is ordered, or when a timeout occurs, it is changed to @ref SOCK_CLOSED regardless of previous status.
+ */
+#define SOCK_CLOSED 0x00
+
+/**
+ * @brief Initiate state
+ * @details This indicates Socket n is opened with TCP mode.\n
+ * It is changed to @ref SOCK_INIT when @ref Sn_MR(P[3:0]) = 001 and OPEN command is ordered.\n
+ * After @ref SOCK_INIT, user can use LISTEN /CONNECT command.
+ */
+#define SOCK_INIT 0x13
+
+/**
+ * @brief Listen state
+ * @details This indicates Socket n is operating as TCP servermode and waiting for connection-request (SYN packet) from a peer TCP client.\n
+ * It will change to @ref SOCK_ESTALBLISHED when the connection-request is successfully accepted.\n
+ * Otherwise it will change to @ref SOCK_CLOSED after TCPTO @ref Sn_IR(TIMEOUT) = '1') is occurred.
+ */
+#define SOCK_LISTEN 0x14
+
+/**
+ * @brief Connection state
+ * @details This indicates Socket n sent the connect-request packet (SYN packet) to a peer.\n
+ * It is temporarily shown when @ref Sn_SR is changed from @ref SOCK_INIT to @ref SOCK_ESTABLISHED by CONNECT command.\n
+ * If connect-accept(SYN/ACK packet) is received from the peer at SOCK_SYNSENT, it changes to @ref SOCK_ESTABLISHED.\n
+ * Otherwise, it changes to @ref SOCK_CLOSED after TCPTO (@ref Sn_IR[TIMEOUT] = '1') is occurred.
+ */
+#define SOCK_SYNSENT 0x15
+
+/**
+ * @brief Connection state
+ * @details It indicates Socket n successfully received the connect-request packet (SYN packet) from a peer.\n
+ * If socket n sends the response (SYN/ACK packet) to the peer successfully, it changes to @ref SOCK_ESTABLISHED. \n
+ * If not, it changes to @ref SOCK_CLOSED after timeout (@ref Sn_IR[TIMEOUT] = '1') is occurred.
+ */
+#define SOCK_SYNRECV 0x16
+
+/**
+ * @brief Success to connect
+ * @details This indicates the status of the connection of Socket n.\n
+ * It changes to @ref SOCK_ESTABLISHED when the TCP SERVERprocessed the SYN packet from the TCP CLIENTduring @ref SOCK_LISTEN, or
+ * when the CONNECT command is successful.\n
+ * During @ref SOCK_ESTABLISHED, DATA packet can be transferred using SEND or RECV command.
+ */
+#define SOCK_ESTABLISHED 0x17
+
+/**
+ * @brief Closing state
+ * @details These indicate Socket n is closing.\n
+ * These are shown in disconnect-process such as active-close and passive-close.\n
+ * When Disconnect-process is successfully completed, or when timeout occurs, these change to @ref SOCK_CLOSED.
+ */
+#define SOCK_FIN_WAIT 0x18
+
+/**
+ * @brief Closing state
+ * @details These indicate Socket n is closing.\n
+ * These are shown in disconnect-process such as active-close and passive-close.\n
+ * When Disconnect-process is successfully completed, or when timeout occurs, these change to @ref SOCK_CLOSED.
+ */
+#define SOCK_CLOSING 0x1A
+
+/**
+ * @brief Closing state
+ * @details These indicate Socket n is closing.\n
+ * These are shown in disconnect-process such as active-close and passive-close.\n
+ * When Disconnect-process is successfully completed, or when timeout occurs, these change to @ref SOCK_CLOSED.
+ */
+#define SOCK_TIME_WAIT 0x1B
+
+/**
+ * @brief Closing state
+ * @details This indicates Socket n received the disconnect-request (FIN packet) from the connected peer.\n
+ * This is half-closing status, and data can be transferred.\n
+ * For full-closing, DISCON command is used. But For just-closing, CLOSE command is used.
+ */
+#define SOCK_CLOSE_WAIT 0x1C
+
+/**
+ * @brief Closing state
+ * @details This indicates Socket n is waiting for the response (FIN/ACK packet) to the disconnect-request (FIN packet) by passive-close.\n
+ * It changes to @ref SOCK_CLOSED when Socket n received the response successfully, or when timeout(@ref Sn_IR[TIMEOUT] = '1') is occurred.
+ */
+#define SOCK_LAST_ACK 0x1D
+
+/**
+ * @brief UDP socket
+ * @details This indicates Socket n is opened in UDP mode(@ref Sn_MR(P[3:0]) = '010').\n
+ * It changes to SOCK_UDP when @ref Sn_MR(P[3:0]) = '010' and @ref Sn_CR_OPEN command is ordered.\n
+ * Unlike TCP mode, data can be transfered without the connection-process.
+ */
+#define SOCK_UDP 0x22
+
+#define SOCK_IPRAW 0x32 /**< IP raw mode socket */
+
+/**
+ * @brief MAC raw mode socket
+ * @details This indicates Socket 0 is opened in MACRAW mode (S0_MR(P[3:0]) = 100and is valid only in Socket 0.\n
+ * It changes to SOCK_MACRAW when S0_MR(P[3:0] = 100and OPEN command is ordered.\n
+ * Like UDP mode socket, MACRAW mode Socket 0 can transfer a MAC packet (Ethernet frame) without the connection-process.
+ */
+#define SOCK_MACRAW 0x42
+
+//#define SOCK_PPPOE 0x5F
+
+/* IP PROTOCOL */
+#define IPPROTO_IP 0 //< Dummy for IP
+#define IPPROTO_ICMP 1 //< Control message protocol
+#define IPPROTO_IGMP 2 //< Internet group management protocol
+#define IPPROTO_GGP 3 //< Gateway^2 (deprecated)
+#define IPPROTO_TCP 6 //< TCP
+#define IPPROTO_PUP 12 //< PUP
+#define IPPROTO_UDP 17 //< UDP
+#define IPPROTO_IDP 22 //< XNS idp
+#define IPPROTO_ND 77 //< UNOFFICIAL net disk protocol
+#define IPPROTO_RAW 255 //< Raw IP packet
+
+
+/**
+ * @brief Enter a critical section
+ *
+ * @details It is provided to protect your shared code which are executed without distribution. \n \n
+ *
+ * In non-OS environment, It can be just implemented by disabling whole interrupt.\n
+ * In OS environment, You can replace it to critical section api supported by OS.
+ *
+ * \sa WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF()
+ * \sa WIZCHIP_CRITICAL_EXIT()
+ */
+#define WIZCHIP_CRITICAL_ENTER() WIZCHIP.CRIS._enter()
+
+#ifdef _exit
+#undef _exit
+#endif
+
+/**
+ * @brief Exit a critical section
+ *
+ * @details It is provided to protect your shared code which are executed without distribution. \n\n
+ *
+ * In non-OS environment, It can be just implemented by disabling whole interrupt. \n
+ * In OS environment, You can replace it to critical section api supported by OS.
+ *
+ * @sa WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF()
+ * @sa WIZCHIP_CRITICAL_ENTER()
+ */
+#define WIZCHIP_CRITICAL_EXIT() WIZCHIP.CRIS._exit()
+
+
+////////////////////////
+// Basic I/O Function //
+////////////////////////
+
+/**
+ * @ingroup Basic_IO_function
+ * @brief It reads 1 byte value from a register.
+ * @param AddrSel Register address
+ * @return The value of register
+ */
+uint8_t WIZCHIP_READ (uint32_t AddrSel);
+
+/**
+ * @ingroup Basic_IO_function
+ * @brief It writes 1 byte value to a register.
+ * @param AddrSel Register address
+ * @param wb Write data
+ * @return void
+ */
+void WIZCHIP_WRITE(uint32_t AddrSel, uint8_t wb );
+
+/**
+ * @ingroup Basic_IO_function
+ * @brief It reads sequence data from registers.
+ * @param AddrSel Register address
+ * @param pBuf Pointer buffer to read data
+ * @param len Data length
+ */
+void WIZCHIP_READ_BUF (uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
+
+/**
+ * @ingroup Basic_IO_function
+ * @brief It writes sequence data to registers.
+ * @param AddrSel Register address
+ * @param pBuf Pointer buffer to write data
+ * @param len Data length
+ */
+void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
+
+/////////////////////////////////
+// Common Register I/O function //
+/////////////////////////////////
+/**
+ * @ingroup Common_register_access_function
+ * @brief Set Mode Register
+ * @param (uint8_t)mr The value to be set.
+ * @sa getMR()
+ */
+#define setMR(mr) \
+ WIZCHIP_WRITE(MR,mr)
+
+
+/**
+ * @ingroup Common_register_access_function
+ * @brief Get Mode Register
+ * @return uint8_t. The value of Mode register.
+ * @sa setMR()
+ */
+#define getMR() \
+ WIZCHIP_READ(MR)
+
+/**
+ * @ingroup Common_register_access_function
+ * @brief Set gateway IP address
+ * @param (uint8_t*)gar Pointer variable to set gateway IP address. It should be allocated 4 bytes.
+ * @sa getGAR()
+ */
+#define setGAR(gar) \
+ WIZCHIP_WRITE_BUF(GAR,gar,4)
+
+/**
+ * @ingroup Common_register_access_function
+ * @brief Get gateway IP address
+ * @param (uint8_t*)gar Pointer variable to get gateway IP address. It should be allocated 4 bytes.
+ * @sa setGAR()
+ */
+#define getGAR(gar) \
+ WIZCHIP_READ_BUF(GAR,gar,4)
+
+/**
+ * @ingroup Common_register_access_function
+ * @brief Set subnet mask address
+ * @param (uint8_t*)subr Pointer variable to set subnet mask address. It should be allocated 4 bytes.
+ * @sa getSUBR()
+ */
+#define setSUBR(subr) \
+ WIZCHIP_WRITE_BUF(SUBR, subr,4)
+
+
+/**
+ * @ingroup Common_register_access_function
+ * @brief Get subnet mask address
+ * @param (uint8_t*)subr Pointer variable to get subnet mask address. It should be allocated 4 bytes.
+ * @sa setSUBR()
+ */
+#define getSUBR(subr) \
+ WIZCHIP_READ_BUF(SUBR, subr, 4)
+
+/**
+ * @ingroup Common_register_access_function
+ * @brief Set local MAC address
+ * @param (uint8_t*)shar Pointer variable to set local MAC address. It should be allocated 6 bytes.
+ * @sa getSHAR()
+ */
+#define setSHAR(shar) \
+ WIZCHIP_WRITE_BUF(SHAR, shar, 6)
+
+/**
+ * @ingroup Common_register_access_function
+ * @brief Get local MAC address
+ * @param (uint8_t*)shar Pointer variable to get local MAC address. It should be allocated 6 bytes.
+ * @sa setSHAR()
+ */
+#define getSHAR(shar) \
+ WIZCHIP_READ_BUF(SHAR, shar, 6)
+
+/**
+ * @ingroup Common_register_access_function
+ * @brief Set local IP address
+ * @param (uint8_t*)sipr Pointer variable to set local IP address. It should be allocated 4 bytes.
+ * @sa getSIPR()
+ */
+#define setSIPR(sipr) \
+ WIZCHIP_WRITE_BUF(SIPR, sipr, 4)
+
+/**
+ * @ingroup Common_register_access_function
+ * @brief Get local IP address
+ * @param (uint8_t*)sipr Pointer variable to get local IP address. It should be allocated 4 bytes.
+ * @sa setSIPR()
+ */
+#define getSIPR(sipr) \
+ WIZCHIP_READ_BUF(SIPR, sipr, 4)
+
+/**
+ * @ingroup Common_register_access_function
+ * @brief Set INTLEVEL register
+ * @param (uint16_t)intlevel Value to set @ref INTLEVEL register.
+ * @sa getINTLEVEL()
+ */
+#define setINTLEVEL(intlevel) {\
+ WIZCHIP_WRITE(INTLEVEL, (uint8_t)(intlevel >> 8)); \
+ WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(INTLEVEL,1), (uint8_t) intlevel); \
+ }
+
+
+/**
+ * @ingroup Common_register_access_function
+ * @brief Get INTLEVEL register
+ * @return uint16_t. Value of @ref INTLEVEL register.
+ * @sa setINTLEVEL()
+ */
+//M20150401 : Type explict declaration
+/*
+#define getINTLEVEL() \
+ ((WIZCHIP_READ(INTLEVEL) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(INTLEVEL,1)))
+*/
+#define getINTLEVEL() \
+ (((uint16_t)WIZCHIP_READ(INTLEVEL) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(INTLEVEL,1)))
+
+/**
+ * @ingroup Common_register_access_function
+ * @brief Set @ref IR register
+ * @param (uint8_t)ir Value to set @ref IR register.
+ * @sa getIR()
+ */
+#define setIR(ir) \
+ WIZCHIP_WRITE(IR, (ir & 0xF0))
+
+/**
+ * @ingroup Common_register_access_function
+ * @brief Get @ref IR register
+ * @return uint8_t. Value of @ref IR register.
+ * @sa setIR()
+ */
+#define getIR() \
+ (WIZCHIP_READ(IR) & 0xF0)
+/**
+ * @ingroup Common_register_access_function
+ * @brief Set @ref _IMR_ register
+ * @param (uint8_t)imr Value to set @ref _IMR_ register.
+ * @sa getIMR()
+ */
+#define setIMR(imr) \
+ WIZCHIP_WRITE(_IMR_, imr)
+
+/**
+ * @ingroup Common_register_access_function
+ * @brief Get @ref _IMR_ register
+ * @return uint8_t. Value of @ref _IMR_ register.
+ * @sa setIMR()
+ */
+#define getIMR() \
+ WIZCHIP_READ(_IMR_)
+
+/**
+ * @ingroup Common_register_access_function
+ * @brief Set @ref SIR register
+ * @param (uint8_t)sir Value to set @ref SIR register.
+ * @sa getSIR()
+ */
+#define setSIR(sir) \
+ WIZCHIP_WRITE(SIR, sir)
+
+/**
+ * @ingroup Common_register_access_function
+ * @brief Get @ref SIR register
+ * @return uint8_t. Value of @ref SIR register.
+ * @sa setSIR()
+ */
+#define getSIR() \
+ WIZCHIP_READ(SIR)
+/**
+ * @ingroup Common_register_access_function
+ * @brief Set @ref SIMR register
+ * @param (uint8_t)simr Value to set @ref SIMR register.
+ * @sa getSIMR()
+ */
+#define setSIMR(simr) \
+ WIZCHIP_WRITE(SIMR, simr)
+
+/**
+ * @ingroup Common_register_access_function
+ * @brief Get @ref SIMR register
+ * @return uint8_t. Value of @ref SIMR register.
+ * @sa setSIMR()
+ */
+#define getSIMR() \
+ WIZCHIP_READ(SIMR)
+
+/**
+ * @ingroup Common_register_access_function
+ * @brief Set @ref _RTR_ register
+ * @param (uint16_t)rtr Value to set @ref _RTR_ register.
+ * @sa getRTR()
+ */
+#define setRTR(rtr) {\
+ WIZCHIP_WRITE(_RTR_, (uint8_t)(rtr >> 8)); \
+ WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(_RTR_,1), (uint8_t) rtr); \
+ }
+
+/**
+ * @ingroup Common_register_access_function
+ * @brief Get @ref _RTR_ register
+ * @return uint16_t. Value of @ref _RTR_ register.
+ * @sa setRTR()
+ */
+//M20150401 : Type explict declaration
+/*
+#define getRTR() \
+ ((WIZCHIP_READ(_RTR_) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(_RTR_,1)))
+*/
+#define getRTR() \
+ (((uint16_t)WIZCHIP_READ(_RTR_) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(_RTR_,1)))
+
+
+/**
+ * @ingroup Common_register_access_function
+ * @brief Set @ref _RCR_ register
+ * @param (uint8_t)rcr Value to set @ref _RCR_ register.
+ * @sa getRCR()
+ */
+#define setRCR(rcr) \
+ WIZCHIP_WRITE(_RCR_, rcr)
+
+/**
+ * @ingroup Common_register_access_function
+ * @brief Get @ref _RCR_ register
+ * @return uint8_t. Value of @ref _RCR_ register.
+ * @sa setRCR()
+ */
+#define getRCR() \
+ WIZCHIP_READ(_RCR_)
+
+//================================================== test done ===========================================================
+
+/**
+ * @ingroup Common_register_access_function
+ * @brief Set @ref PTIMER register
+ * @param (uint8_t)ptimer Value to set @ref PTIMER register.
+ * @sa getPTIMER()
+ */
+#define setPTIMER(ptimer) \
+ WIZCHIP_WRITE(PTIMER, ptimer)
+
+/**
+ * @ingroup Common_register_access_function
+ * @brief Get @ref PTIMER register
+ * @return uint8_t. Value of @ref PTIMER register.
+ * @sa setPTIMER()
+ */
+#define getPTIMER() \
+ WIZCHIP_READ(PTIMER)
+
+/**
+ * @ingroup Common_register_access_function
+ * @brief Set @ref PMAGIC register
+ * @param (uint8_t)pmagic Value to set @ref PMAGIC register.
+ * @sa getPMAGIC()
+ */
+#define setPMAGIC(pmagic) \
+ WIZCHIP_WRITE(PMAGIC, pmagic)
+
+/**
+ * @ingroup Common_register_access_function
+ * @brief Get @ref PMAGIC register
+ * @return uint8_t. Value of @ref PMAGIC register.
+ * @sa setPMAGIC()
+ */
+#define getPMAGIC() \
+ WIZCHIP_READ(PMAGIC)
+
+/**
+ * @ingroup Common_register_access_function
+ * @brief Set @ref PHAR address
+ * @param (uint8_t*)phar Pointer variable to set PPP destination MAC register address. It should be allocated 6 bytes.
+ * @sa getPHAR()
+ */
+#define setPHAR(phar) \
+ WIZCHIP_WRITE_BUF(PHAR, phar, 6)
+
+/**
+ * @ingroup Common_register_access_function
+ * @brief Get @ref PHAR address
+ * @param (uint8_t*)phar Pointer variable to PPP destination MAC register address. It should be allocated 6 bytes.
+ * @sa setPHAR()
+ */
+#define getPHAR(phar) \
+ WIZCHIP_READ_BUF(PHAR, phar, 6)
+
+/**
+ * @ingroup Common_register_access_function
+ * @brief Set @ref PSID register
+ * @param (uint16_t)psid Value to set @ref PSID register.
+ * @sa getPSID()
+ */
+#define setPSID(psid) {\
+ WIZCHIP_WRITE(PSID, (uint8_t)(psid >> 8)); \
+ WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(PSID,1), (uint8_t) psid); \
+ }
+
+/**
+ * @ingroup Common_register_access_function
+ * @brief Get @ref PSID register
+ * @return uint16_t. Value of @ref PSID register.
+ * @sa setPSID()
+ */
+//uint16_t getPSID(void);
+//M20150401 : Type explict declaration
+/*
+#define getPSID() \
+ ((WIZCHIP_READ(PSID) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(PSID,1)))
+*/
+#define getPSID() \
+ (((uint16_t)WIZCHIP_READ(PSID) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(PSID,1)))
+
+/**
+ * @ingroup Common_register_access_function
+ * @brief Set @ref PMRU register
+ * @param (uint16_t)pmru Value to set @ref PMRU register.
+ * @sa getPMRU()
+ */
+#define setPMRU(pmru) { \
+ WIZCHIP_WRITE(PMRU, (uint8_t)(pmru>>8)); \
+ WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(PMRU,1), (uint8_t) pmru); \
+ }
+
+/**
+ * @ingroup Common_register_access_function
+ * @brief Get @ref PMRU register
+ * @return uint16_t. Value of @ref PMRU register.
+ * @sa setPMRU()
+ */
+//M20150401 : Type explict declaration
+/*
+#define getPMRU() \
+ ((WIZCHIP_READ(PMRU) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(PMRU,1)))
+*/
+#define getPMRU() \
+ (((uint16_t)WIZCHIP_READ(PMRU) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(PMRU,1)))
+
+/**
+ * @ingroup Common_register_access_function
+ * @brief Get unreachable IP address
+ * @param (uint8_t*)uipr Pointer variable to get unreachable IP address. It should be allocated 4 bytes.
+ */
+//M20150401 : Size Error of UIPR (6 -> 4)
+/*
+#define getUIPR(uipr) \
+ WIZCHIP_READ_BUF(UIPR,uipr,6)
+*/
+#define getUIPR(uipr) \
+ WIZCHIP_READ_BUF(UIPR,uipr,4)
+
+/**
+ * @ingroup Common_register_access_function
+ * @brief Get @ref UPORTR register
+ * @return uint16_t. Value of @ref UPORTR register.
+ */
+//M20150401 : Type explict declaration
+/*
+#define getUPORTR() \
+ ((WIZCHIP_READ(UPORTR) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(UPORTR,1)))
+*/
+#define getUPORTR() \
+ (((uint16_t)WIZCHIP_READ(UPORTR) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(UPORTR,1)))
+
+/**
+ * @ingroup Common_register_access_function
+ * @brief Set @ref PHYCFGR register
+ * @param (uint8_t)phycfgr Value to set @ref PHYCFGR register.
+ * @sa getPHYCFGR()
+ */
+#define setPHYCFGR(phycfgr) \
+ WIZCHIP_WRITE(PHYCFGR, phycfgr)
+
+/**
+ * @ingroup Common_register_access_function
+ * @brief Get @ref PHYCFGR register
+ * @return uint8_t. Value of @ref PHYCFGR register.
+ * @sa setPHYCFGR()
+ */
+#define getPHYCFGR() \
+ WIZCHIP_READ(PHYCFGR)
+
+/**
+ * @ingroup Common_register_access_function
+ * @brief Get @ref VERSIONR register
+ * @return uint8_t. Value of @ref VERSIONR register.
+ */
+#define getVERSIONR() \
+ WIZCHIP_READ(VERSIONR)
+
+#define getVER() \
+ getVERSIONR()
+
+/////////////////////////////////////
+
+///////////////////////////////////
+// Socket N register I/O function //
+///////////////////////////////////
+/**
+ * @ingroup Socket_register_access_function
+ * @brief Set @ref Sn_MR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @param (uint8_t)mr Value to set @ref Sn_MR
+ * @sa getSn_MR()
+ */
+#define setSn_MR(sn, mr) \
+ WIZCHIP_WRITE(Sn_MR(sn),mr)
+
+/**
+ * @ingroup Socket_register_access_function
+ * @brief Get @ref Sn_MR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @return uint8_t. Value of @ref Sn_MR.
+ * @sa setSn_MR()
+ */
+#define getSn_MR(sn) \
+ WIZCHIP_READ(Sn_MR(sn))
+
+/**
+ * @ingroup Socket_register_access_function
+ * @brief Set @ref Sn_CR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @param (uint8_t)cr Value to set @ref Sn_CR
+ * @sa getSn_CR()
+ */
+#define setSn_CR(sn, cr) \
+ WIZCHIP_WRITE(Sn_CR(sn), cr)
+
+/**
+ * @ingroup Socket_register_access_function
+ * @brief Get @ref Sn_CR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @return uint8_t. Value of @ref Sn_CR.
+ * @sa setSn_CR()
+ */
+#define getSn_CR(sn) \
+ WIZCHIP_READ(Sn_CR(sn))
+
+/**
+ * @ingroup Socket_register_access_function
+ * @brief Set @ref Sn_IR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @param (uint8_t)ir Value to set @ref Sn_IR
+ * @sa getSn_IR()
+ */
+#define setSn_IR(sn, ir) \
+ WIZCHIP_WRITE(Sn_IR(sn), (ir & 0x1F))
+
+/**
+ * @ingroup Socket_register_access_function
+ * @brief Get @ref Sn_IR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @return uint8_t. Value of @ref Sn_IR.
+ * @sa setSn_IR()
+ */
+#define getSn_IR(sn) \
+ (WIZCHIP_READ(Sn_IR(sn)) & 0x1F)
+
+/**
+ * @ingroup Socket_register_access_function
+ * @brief Set @ref Sn_IMR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @param (uint8_t)imr Value to set @ref Sn_IMR
+ * @sa getSn_IMR()
+ */
+#define setSn_IMR(sn, imr) \
+ WIZCHIP_WRITE(Sn_IMR(sn), (imr & 0x1F))
+
+/**
+ * @ingroup Socket_register_access_function
+ * @brief Get @ref Sn_IMR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @return uint8_t. Value of @ref Sn_IMR.
+ * @sa setSn_IMR()
+ */
+#define getSn_IMR(sn) \
+ (WIZCHIP_READ(Sn_IMR(sn)) & 0x1F)
+
+/**
+ * @ingroup Socket_register_access_function
+ * @brief Get @ref Sn_SR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @return uint8_t. Value of @ref Sn_SR.
+ */
+#define getSn_SR(sn) \
+ WIZCHIP_READ(Sn_SR(sn))
+
+/**
+ * @ingroup Socket_register_access_function
+ * @brief Set @ref Sn_PORT register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @param (uint16_t)port Value to set @ref Sn_PORT.
+ * @sa getSn_PORT()
+ */
+#define setSn_PORT(sn, port) { \
+ WIZCHIP_WRITE(Sn_PORT(sn), (uint8_t)(port >> 8)); \
+ WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_PORT(sn),1), (uint8_t) port); \
+ }
+
+/**
+ * @ingroup Socket_register_access_function
+ * @brief Get @ref Sn_PORT register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @return uint16_t. Value of @ref Sn_PORT.
+ * @sa setSn_PORT()
+ */
+//M20150401 : Type explict declaration
+/*
+#define getSn_PORT(sn) \
+ ((WIZCHIP_READ(Sn_PORT(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_PORT(sn),1)))
+*/
+#define getSn_PORT(sn) \
+ (((uint16_t)WIZCHIP_READ(Sn_PORT(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_PORT(sn),1)))
+
+/**
+ * @ingroup Socket_register_access_function
+ * @brief Set @ref Sn_DHAR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @param (uint8_t*)dhar Pointer variable to set socket n destination hardware address. It should be allocated 6 bytes.
+ * @sa getSn_DHAR()
+ */
+#define setSn_DHAR(sn, dhar) \
+ WIZCHIP_WRITE_BUF(Sn_DHAR(sn), dhar, 6)
+
+/**
+ * @ingroup Socket_register_access_function
+ * @brief Get @ref Sn_MR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @param (uint8_t*)dhar Pointer variable to get socket n destination hardware address. It should be allocated 6 bytes.
+ * @sa setSn_DHAR()
+ */
+#define getSn_DHAR(sn, dhar) \
+ WIZCHIP_READ_BUF(Sn_DHAR(sn), dhar, 6)
+
+/**
+ * @ingroup Socket_register_access_function
+ * @brief Set @ref Sn_DIPR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @param (uint8_t*)dipr Pointer variable to set socket n destination IP address. It should be allocated 4 bytes.
+ * @sa getSn_DIPR()
+ */
+#define setSn_DIPR(sn, dipr) \
+ WIZCHIP_WRITE_BUF(Sn_DIPR(sn), dipr, 4)
+
+/**
+ * @ingroup Socket_register_access_function
+ * @brief Get @ref Sn_DIPR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @param (uint8_t*)dipr Pointer variable to get socket n destination IP address. It should be allocated 4 bytes.
+ * @sa setSn_DIPR()
+ */
+#define getSn_DIPR(sn, dipr) \
+ WIZCHIP_READ_BUF(Sn_DIPR(sn), dipr, 4)
+
+/**
+ * @ingroup Socket_register_access_function
+ * @brief Set @ref Sn_DPORT register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @param (uint16_t)dport Value to set @ref Sn_DPORT
+ * @sa getSn_DPORT()
+ */
+#define setSn_DPORT(sn, dport) { \
+ WIZCHIP_WRITE(Sn_DPORT(sn), (uint8_t) (dport>>8)); \
+ WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_DPORT(sn),1), (uint8_t) dport); \
+ }
+
+/**
+ * @ingroup Socket_register_access_function
+ * @brief Get @ref Sn_DPORT register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @return uint16_t. Value of @ref Sn_DPORT.
+ * @sa setSn_DPORT()
+ */
+//M20150401 : Type explict declaration
+/*
+#define getSn_DPORT(sn) \
+ ((WIZCHIP_READ(Sn_DPORT(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_DPORT(sn),1)))
+*/
+#define getSn_DPORT(sn) \
+ (((uint16_t)WIZCHIP_READ(Sn_DPORT(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_DPORT(sn),1)))
+
+/**
+ * @ingroup Socket_register_access_function
+ * @brief Set @ref Sn_MSSR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @param (uint16_t)mss Value to set @ref Sn_MSSR
+ * @sa setSn_MSSR()
+ */
+#define setSn_MSSR(sn, mss) { \
+ WIZCHIP_WRITE(Sn_MSSR(sn), (uint8_t)(mss>>8)); \
+ WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_MSSR(sn),1), (uint8_t) mss); \
+ }
+
+/**
+ * @ingroup Socket_register_access_function
+ * @brief Get @ref Sn_MSSR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @return uint16_t. Value of @ref Sn_MSSR.
+ * @sa setSn_MSSR()
+ */
+//M20150401 : Type explict declaration
+/*
+#define getSn_MSSR(sn) \
+ ((WIZCHIP_READ(Sn_MSSR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_MSSR(sn),1)))
+*/
+#define getSn_MSSR(sn) \
+ (((uint16_t)WIZCHIP_READ(Sn_MSSR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_MSSR(sn),1)))
+
+/**
+ * @ingroup Socket_register_access_function
+ * @brief Set @ref Sn_TOS register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @param (uint8_t)tos Value to set @ref Sn_TOS
+ * @sa getSn_TOS()
+ */
+#define setSn_TOS(sn, tos) \
+ WIZCHIP_WRITE(Sn_TOS(sn), tos)
+
+/**
+ * @ingroup Socket_register_access_function
+ * @brief Get @ref Sn_TOS register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @return uint8_t. Value of Sn_TOS.
+ * @sa setSn_TOS()
+ */
+#define getSn_TOS(sn) \
+ WIZCHIP_READ(Sn_TOS(sn))
+
+/**
+ * @ingroup Socket_register_access_function
+ * @brief Set @ref Sn_TTL register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @param (uint8_t)ttl Value to set @ref Sn_TTL
+ * @sa getSn_TTL()
+ */
+#define setSn_TTL(sn, ttl) \
+ WIZCHIP_WRITE(Sn_TTL(sn), ttl)
+
+
+/**
+ * @ingroup Socket_register_access_function
+ * @brief Get @ref Sn_TTL register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @return uint8_t. Value of @ref Sn_TTL.
+ * @sa setSn_TTL()
+ */
+#define getSn_TTL(sn) \
+ WIZCHIP_READ(Sn_TTL(sn))
+
+
+/**
+ * @ingroup Socket_register_access_function
+ * @brief Set @ref Sn_RXBUF_SIZE register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @param (uint8_t)rxbufsize Value to set @ref Sn_RXBUF_SIZE
+ * @sa getSn_RXBUF_SIZE()
+ */
+#define setSn_RXBUF_SIZE(sn, rxbufsize) \
+ WIZCHIP_WRITE(Sn_RXBUF_SIZE(sn),rxbufsize)
+
+
+/**
+ * @ingroup Socket_register_access_function
+ * @brief Get @ref Sn_RXBUF_SIZE register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @return uint8_t. Value of @ref Sn_RXBUF_SIZE.
+ * @sa setSn_RXBUF_SIZE()
+ */
+#define getSn_RXBUF_SIZE(sn) \
+ WIZCHIP_READ(Sn_RXBUF_SIZE(sn))
+
+/**
+ * @ingroup Socket_register_access_function
+ * @brief Set @ref Sn_TXBUF_SIZE register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @param (uint8_t)txbufsize Value to set @ref Sn_TXBUF_SIZE
+ * @sa getSn_TXBUF_SIZE()
+ */
+#define setSn_TXBUF_SIZE(sn, txbufsize) \
+ WIZCHIP_WRITE(Sn_TXBUF_SIZE(sn), txbufsize)
+
+/**
+ * @ingroup Socket_register_access_function
+ * @brief Get @ref Sn_TXBUF_SIZE register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @return uint8_t. Value of @ref Sn_TXBUF_SIZE.
+ * @sa setSn_TXBUF_SIZE()
+ */
+#define getSn_TXBUF_SIZE(sn) \
+ WIZCHIP_READ(Sn_TXBUF_SIZE(sn))
+
+/**
+ * @ingroup Socket_register_access_function
+ * @brief Get @ref Sn_TX_FSR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @return uint16_t. Value of @ref Sn_TX_FSR.
+ */
+uint16_t getSn_TX_FSR(uint8_t sn);
+
+/**
+ * @ingroup Socket_register_access_function
+ * @brief Get @ref Sn_TX_RD register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @return uint16_t. Value of @ref Sn_TX_RD.
+ */
+//M20150401 : Type explict declaration
+/*
+#define getSn_TX_RD(sn) \
+ ((WIZCHIP_READ(Sn_TX_RD(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_RD(sn),1)))
+*/
+#define getSn_TX_RD(sn) \
+ (((uint16_t)WIZCHIP_READ(Sn_TX_RD(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_RD(sn),1)))
+
+/**
+ * @ingroup Socket_register_access_function
+ * @brief Set @ref Sn_TX_WR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @param (uint16_t)txwr Value to set @ref Sn_TX_WR
+ * @sa GetSn_TX_WR()
+ */
+#define setSn_TX_WR(sn, txwr) { \
+ WIZCHIP_WRITE(Sn_TX_WR(sn), (uint8_t)(txwr>>8)); \
+ WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_TX_WR(sn),1), (uint8_t) txwr); \
+ }
+
+/**
+ * @ingroup Socket_register_access_function
+ * @brief Get @ref Sn_TX_WR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @return uint16_t. Value of @ref Sn_TX_WR.
+ * @sa setSn_TX_WR()
+ */
+//M20150401 : Type explict declaration
+/*
+#define getSn_TX_WR(sn) \
+ ((WIZCHIP_READ(Sn_TX_WR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_WR(sn),1)))
+*/
+#define getSn_TX_WR(sn) \
+ (((uint16_t)WIZCHIP_READ(Sn_TX_WR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_WR(sn),1)))
+
+
+/**
+ * @ingroup Socket_register_access_function
+ * @brief Get @ref Sn_RX_RSR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @return uint16_t. Value of @ref Sn_RX_RSR.
+ */
+uint16_t getSn_RX_RSR(uint8_t sn);
+
+
+/**
+ * @ingroup Socket_register_access_function
+ * @brief Set @ref Sn_RX_RD register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @param (uint16_t)rxrd Value to set @ref Sn_RX_RD
+ * @sa getSn_RX_RD()
+ */
+#define setSn_RX_RD(sn, rxrd) { \
+ WIZCHIP_WRITE(Sn_RX_RD(sn), (uint8_t)(rxrd>>8)); \
+ WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_RX_RD(sn),1), (uint8_t) rxrd); \
+ }
+
+/**
+ * @ingroup Socket_register_access_function
+ * @brief Get @ref Sn_RX_RD register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @return uint16_t. Value of @ref Sn_RX_RD.
+ * @sa setSn_RX_RD()
+ */
+//M20150401 : Type explict declaration
+/*
+#define getSn_RX_RD(sn) \
+ ((WIZCHIP_READ(Sn_RX_RD(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RD(sn),1)))
+*/
+#define getSn_RX_RD(sn) \
+ (((uint16_t)WIZCHIP_READ(Sn_RX_RD(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RD(sn),1)))
+
+/**
+ * @ingroup Socket_register_access_function
+ * @brief Get @ref Sn_RX_WR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @return uint16_t. Value of @ref Sn_RX_WR.
+ */
+//M20150401 : Type explict declaration
+/*
+#define getSn_RX_WR(sn) \
+ ((WIZCHIP_READ(Sn_RX_WR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_WR(sn),1)))
+*/
+#define getSn_RX_WR(sn) \
+ (((uint16_t)WIZCHIP_READ(Sn_RX_WR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_WR(sn),1)))
+
+/**
+ * @ingroup Socket_register_access_function
+ * @brief Set @ref Sn_FRAG register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @param (uint16_t)frag Value to set @ref Sn_FRAG
+ * @sa getSn_FRAD()
+ */
+#define setSn_FRAG(sn, frag) { \
+ WIZCHIP_WRITE(Sn_FRAG(sn), (uint8_t)(frag >>8)); \
+ WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_FRAG(sn),1), (uint8_t) frag); \
+ }
+
+/**
+ * @ingroup Socket_register_access_function
+ * @brief Get @ref Sn_FRAG register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @return uint16_t. Value of @ref Sn_FRAG.
+ * @sa setSn_FRAG()
+ */
+//M20150401 : Type explict declaration
+/*
+#define getSn_FRAG(sn) \
+ ((WIZCHIP_READ(Sn_FRAG(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_FRAG(sn),1)))
+*/
+#define getSn_FRAG(sn) \
+ (((uint16_t)WIZCHIP_READ(Sn_FRAG(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_FRAG(sn),1)))
+
+/**
+ * @ingroup Socket_register_access_function
+ * @brief Set @ref Sn_KPALVTR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @param (uint8_t)kpalvt Value to set @ref Sn_KPALVTR
+ * @sa getSn_KPALVTR()
+ */
+#define setSn_KPALVTR(sn, kpalvt) \
+ WIZCHIP_WRITE(Sn_KPALVTR(sn), kpalvt)
+
+/**
+ * @ingroup Socket_register_access_function
+ * @brief Get @ref Sn_KPALVTR register
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @return uint8_t. Value of @ref Sn_KPALVTR.
+ * @sa setSn_KPALVTR()
+ */
+#define getSn_KPALVTR(sn) \
+ WIZCHIP_READ(Sn_KPALVTR(sn))
+
+//////////////////////////////////////
+
+/////////////////////////////////////
+// Sn_TXBUF & Sn_RXBUF IO function //
+/////////////////////////////////////
+/**
+ * @brief Socket_register_access_function
+ * @brief Gets the max buffer size of socket sn passed as parameter.
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @return uint16_t. Value of Socket n RX max buffer size.
+ */
+//M20150401 : Type explict declaration
+/*
+#define getSn_RxMAX(sn) \
+ (getSn_RXBUF_SIZE(sn) << 10)
+*/
+#define getSn_RxMAX(sn) \
+ (((uint16_t)getSn_RXBUF_SIZE(sn)) << 10)
+
+/**
+ * @brief Socket_register_access_function
+ * @brief Gets the max buffer size of socket sn passed as parameters.
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @return uint16_t. Value of Socket n TX max buffer size.
+ */
+//M20150401 : Type explict declaration
+/*
+#define getSn_TxMAX(sn) \
+ (getSn_TXBUF_SIZE(sn) << 10)
+*/
+#define getSn_TxMAX(sn) \
+ (((uint16_t)getSn_TXBUF_SIZE(sn)) << 10)
+
+/**
+ * @ingroup Basic_IO_function
+ * @brief It copies data to internal TX memory
+ *
+ * @details This function reads the Tx write pointer register and after that,
+ * it copies the wizdata(pointer buffer) of the length of len(variable) bytes to internal TX memory
+ * and updates the Tx write pointer register.
+ * This function is being called by send() and sendto() function also.
+ *
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @param wizdata Pointer buffer to write data
+ * @param len Data length
+ * @sa wiz_recv_data()
+ */
+void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint16_t len);
+
+/**
+ * @ingroup Basic_IO_function
+ * @brief It copies data to your buffer from internal RX memory
+ *
+ * @details This function read the Rx read pointer register and after that,
+ * it copies the received data from internal RX memory
+ * to wizdata(pointer variable) of the length of len(variable) bytes.
+ * This function is being called by recv() also.
+ *
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @param wizdata Pointer buffer to read data
+ * @param len Data length
+ * @sa wiz_send_data()
+ */
+void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len);
+
+/**
+ * @ingroup Basic_IO_function
+ * @brief It discard the received data in RX memory.
+ * @details It discards the data of the length of len(variable) bytes in internal RX memory.
+ * @param (uint8_t)sn Socket number. It should be 0 ~ 7.
+ * @param len Data length
+ */
+void wiz_recv_ignore(uint8_t sn, uint16_t len);
+
+/// @cond DOXY_APPLY_CODE
+#endif
+/// @endcond
+
+#endif // _W5500_H_
diff --git a/Libraries/ioLibrary_Driver/Ethernet/socket.c b/Libraries/ioLibrary_Driver/Ethernet/socket.c
new file mode 100644
index 0000000..acd1ffc
--- /dev/null
+++ b/Libraries/ioLibrary_Driver/Ethernet/socket.c
@@ -0,0 +1,930 @@
+//*****************************************************************************
+//
+//! \file socket.c
+//! \brief SOCKET APIs Implements file.
+//! \details SOCKET APIs like as Berkeley Socket APIs.
+//! \version 1.0.3
+//! \date 2013/10/21
+//! \par Revision history
+//! <2015/02/05> Notice
+//! The version history is not updated after this point.
+//! Download the latest version directly from GitHub. Please visit the our GitHub repository for ioLibrary.
+//! >> https://github.com/Wiznet/ioLibrary_Driver
+//! <2014/05/01> V1.0.3. Refer to M20140501
+//! 1. Implicit type casting -> Explicit type casting.
+//! 2. replace 0x01 with PACK_REMAINED in recvfrom()
+//! 3. Validation a destination ip in connect() & sendto():
+//! It occurs a fatal error on converting unint32 address if uint8* addr parameter is not aligned by 4byte address.
+//! Copy 4 byte addr value into temporary uint32 variable and then compares it.
+//! <2013/12/20> V1.0.2 Refer to M20131220
+//! Remove Warning.
+//! <2013/11/04> V1.0.1 2nd Release. Refer to "20131104".
+//! In sendto(), Add to clear timeout interrupt status (Sn_IR_TIMEOUT)
+//! <2013/10/21> 1st Release
+//! \author MidnightCow
+//! \copyright
+//!
+//! Copyright (c) 2013, WIZnet Co., LTD.
+//! All rights reserved.
+//!
+//! Redistribution and use in source and binary forms, with or without
+//! modification, are permitted provided that the following conditions
+//! are met:
+//!
+//! * Redistributions of source code must retain the above copyright
+//! notice, this list of conditions and the following disclaimer.
+//! * Redistributions in binary form must reproduce the above copyright
+//! notice, this list of conditions and the following disclaimer in the
+//! documentation and/or other materials provided with the distribution.
+//! * Neither the name of the nor the names of its
+//! contributors may be used to endorse or promote products derived
+//! from this software without specific prior written permission.
+//!
+//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+//! THE POSSIBILITY OF SUCH DAMAGE.
+//
+//*****************************************************************************
+#include "../../ioLibrary_Driver/Ethernet/socket.h"
+
+//M20150401 : Typing Error
+//#define SOCK_ANY_PORT_NUM 0xC000;
+#define SOCK_ANY_PORT_NUM 0xC000
+
+static uint16_t sock_any_port = SOCK_ANY_PORT_NUM;
+static uint16_t sock_io_mode = 0;
+static uint16_t sock_is_sending = 0;
+
+static uint16_t sock_remained_size[_WIZCHIP_SOCK_NUM_] = {0,0,};
+
+//M20150601 : For extern decleation
+//static uint8_t sock_pack_info[_WIZCHIP_SOCK_NUM_] = {0,};
+uint8_t sock_pack_info[_WIZCHIP_SOCK_NUM_] = {0,};
+//
+
+#if _WIZCHIP_ == 5200
+ static uint16_t sock_next_rd[_WIZCHIP_SOCK_NUM_] ={0,};
+#endif
+
+//A20150601 : For integrating with W5300
+#if _WIZCHIP_ == 5300
+ uint8_t sock_remained_byte[_WIZCHIP_SOCK_NUM_] = {0,}; // set by wiz_recv_data()
+#endif
+
+
+#define CHECK_SOCKNUM() \
+ do{ \
+ if(sn > _WIZCHIP_SOCK_NUM_) return SOCKERR_SOCKNUM; \
+ }while(0); \
+
+#define CHECK_SOCKMODE(mode) \
+ do{ \
+ if((getSn_MR(sn) & 0x0F) != mode) return SOCKERR_SOCKMODE; \
+ }while(0); \
+
+#define CHECK_SOCKINIT() \
+ do{ \
+ if((getSn_SR(sn) != SOCK_INIT)) return SOCKERR_SOCKINIT; \
+ }while(0); \
+
+#define CHECK_SOCKDATA() \
+ do{ \
+ if(len == 0) return SOCKERR_DATALEN; \
+ }while(0); \
+
+
+
+int8_t socket(uint8_t sn, uint8_t protocol, uint16_t port, uint8_t flag)
+{
+ CHECK_SOCKNUM();
+ switch(protocol)
+ {
+ case Sn_MR_TCP :
+ {
+ //M20150601 : Fixed the warning - taddr will never be NULL
+ /*
+ uint8_t taddr[4];
+ getSIPR(taddr);
+ */
+ uint32_t taddr;
+ getSIPR((uint8_t*)&taddr);
+ if(taddr == 0) return SOCKERR_SOCKINIT;
+ }
+ case Sn_MR_UDP :
+ case Sn_MR_MACRAW :
+ case Sn_MR_IPRAW :
+ break;
+ #if ( _WIZCHIP_ < 5200 )
+ case Sn_MR_PPPoE :
+ break;
+ #endif
+ default :
+ return SOCKERR_SOCKMODE;
+ }
+ //M20150601 : For SF_TCP_ALIGN & W5300
+ //if((flag & 0x06) != 0) return SOCKERR_SOCKFLAG;
+ if((flag & 0x04) != 0) return SOCKERR_SOCKFLAG;
+#if _WIZCHIP_ == 5200
+ if(flag & 0x10) return SOCKERR_SOCKFLAG;
+#endif
+
+ if(flag != 0)
+ {
+ switch(protocol)
+ {
+ case Sn_MR_TCP:
+ //M20150601 : For SF_TCP_ALIGN & W5300
+ #if _WIZCHIP_ == 5300
+ if((flag & (SF_TCP_NODELAY|SF_IO_NONBLOCK|SF_TCP_ALIGN))==0) return SOCKERR_SOCKFLAG;
+ #else
+ if((flag & (SF_TCP_NODELAY|SF_IO_NONBLOCK))==0) return SOCKERR_SOCKFLAG;
+ #endif
+
+ break;
+ case Sn_MR_UDP:
+ if(flag & SF_IGMP_VER2)
+ {
+ if((flag & SF_MULTI_ENABLE)==0) return SOCKERR_SOCKFLAG;
+ }
+ #if _WIZCHIP_ == 5500
+ if(flag & SF_UNI_BLOCK)
+ {
+ if((flag & SF_MULTI_ENABLE) == 0) return SOCKERR_SOCKFLAG;
+ }
+ #endif
+ break;
+ default:
+ break;
+ }
+ }
+ close(sn);
+ //M20150601
+ #if _WIZCHIP_ == 5300
+ setSn_MR(sn, ((uint16_t)(protocol | (flag & 0xF0))) | (((uint16_t)(flag & 0x02)) << 7) );
+ #else
+ setSn_MR(sn, (protocol | (flag & 0xF0)));
+ #endif
+ if(!port)
+ {
+ port = sock_any_port++;
+ if(sock_any_port == 0xFFF0) sock_any_port = SOCK_ANY_PORT_NUM;
+ }
+ setSn_PORT(sn,port);
+ setSn_CR(sn,Sn_CR_OPEN);
+ while(getSn_CR(sn));
+ //A20150401 : For release the previous sock_io_mode
+ sock_io_mode &= ~(1 < sn
+ //if( ((getSn_MR(s)& 0x0F) == Sn_MR_TCP) && (getSn_TX_FSR(s) != getSn_TxMAX(s)) )
+ if( ((getSn_MR(sn)& 0x0F) == Sn_MR_TCP) && (getSn_TX_FSR(sn) != getSn_TxMAX(sn)) )
+ {
+ uint8_t destip[4] = {0, 0, 0, 1};
+ // TODO
+ // You can wait for completing to sending data;
+ // wait about 1 second;
+ // if you have completed to send data, skip the code of erratum 1
+ // ex> wait_1s();
+ // if (getSn_TX_FSR(s) == getSn_TxMAX(s)) continue;
+ //
+ //M20160503 : The socket() of close() calls close() itself again. It occures a infinite loop - close()->socket()->close()->socket()-> ~
+ //socket(s,Sn_MR_UDP,0x3000,0);
+ //sendto(s,destip,1,destip,0x3000); // send the dummy data to an unknown destination(0.0.0.1).
+ setSn_MR(sn,Sn_MR_UDP);
+ setSn_PORTR(sn, 0x3000);
+ setSn_CR(sn,Sn_CR_OPEN);
+ while(getSn_CR(sn) != 0);
+ while(getSn_SR(sn) != SOCK_UDP);
+ sendto(sn,destip,1,destip,0x3000); // send the dummy data to an unknown destination(0.0.0.1).
+ };
+#endif
+ setSn_CR(sn,Sn_CR_CLOSE);
+ /* wait to process the command... */
+ while( getSn_CR(sn) );
+ /* clear all interrupt of the socket. */
+ setSn_IR(sn, 0xFF);
+ //A20150401 : Release the sock_io_mode of socket n.
+ sock_io_mode &= ~(1< freesize) len = freesize; // check size not to exceed MAX size.
+ while(1)
+ {
+ freesize = getSn_TX_FSR(sn);
+ tmp = getSn_SR(sn);
+ if ((tmp != SOCK_ESTABLISHED) && (tmp != SOCK_CLOSE_WAIT))
+ {
+ close(sn);
+ return SOCKERR_SOCKSTATUS;
+ }
+ if( (sock_io_mode & (1< freesize) ) return SOCK_BUSY;
+ if(len <= freesize) break;
+ }
+ wiz_send_data(sn, buf, len);
+ #if _WIZCHIP_ == 5200
+ sock_next_rd[sn] = getSn_TX_RD(sn) + len;
+ #endif
+
+ #if _WIZCHIP_ == 5300
+ setSn_TX_WRSR(sn,len);
+ #endif
+
+ setSn_CR(sn,Sn_CR_SEND);
+ /* wait to process the command... */
+ while(getSn_CR(sn));
+ sock_is_sending |= (1 << sn);
+ //M20150409 : Explicit Type Casting
+ //return len;
+ return (int32_t)len;
+}
+
+
+int32_t recv(uint8_t sn, uint8_t * buf, uint16_t len)
+{
+ uint8_t tmp = 0;
+ uint16_t recvsize = 0;
+//A20150601 : For integarating with W5300
+#if _WIZCHIP_ == 5300
+ uint8_t head[2];
+ uint16_t mr;
+#endif
+//
+ CHECK_SOCKNUM();
+ CHECK_SOCKMODE(Sn_MR_TCP);
+ CHECK_SOCKDATA();
+
+ recvsize = getSn_RxMAX(sn);
+ if(recvsize < len) len = recvsize;
+
+//A20150601 : For Integrating with W5300
+#if _WIZCHIP_ == 5300
+ //sock_pack_info[sn] = PACK_COMPLETED; // for clear
+ if(sock_remained_size[sn] == 0)
+ {
+#endif
+//
+ while(1)
+ {
+ recvsize = getSn_RX_RSR(sn);
+ tmp = getSn_SR(sn);
+ if (tmp != SOCK_ESTABLISHED)
+ {
+ if(tmp == SOCK_CLOSE_WAIT)
+ {
+ if(recvsize != 0) break;
+ else if(getSn_TX_FSR(sn) == getSn_TxMAX(sn))
+ {
+ close(sn);
+ return SOCKERR_SOCKSTATUS;
+ }
+ }
+ else
+ {
+ close(sn);
+ return SOCKERR_SOCKSTATUS;
+ }
+ }
+ if((sock_io_mode & (1< sock_remained_size[sn]) len = sock_remained_size[sn];
+ recvsize = len;
+ if(sock_pack_info[sn] & PACK_FIFOBYTE)
+ {
+ *buf = sock_remained_byte[sn];
+ buf++;
+ sock_pack_info[sn] &= ~(PACK_FIFOBYTE);
+ recvsize -= 1;
+ sock_remained_size[sn] -= 1;
+ }
+ if(recvsize != 0)
+ {
+ wiz_recv_data(sn, buf, recvsize);
+ setSn_CR(sn,Sn_CR_RECV);
+ while(getSn_CR(sn));
+ }
+ sock_remained_size[sn] -= recvsize;
+ if(sock_remained_size[sn] != 0)
+ {
+ sock_pack_info[sn] |= PACK_REMAINED;
+ if(recvsize & 0x1) sock_pack_info[sn] |= PACK_FIFOBYTE;
+ }
+ else sock_pack_info[sn] = PACK_COMPLETED;
+ if(getSn_MR(sn) & Sn_MR_ALIGN) sock_remained_size[sn] = 0;
+ //len = recvsize;
+#else
+ if(recvsize < len) len = recvsize;
+ wiz_recv_data(sn, buf, len);
+ setSn_CR(sn,Sn_CR_RECV);
+ while(getSn_CR(sn));
+#endif
+
+ //M20150409 : Explicit Type Casting
+ //return len;
+ return (int32_t)len;
+}
+
+int32_t sendto(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t port)
+{
+ uint8_t tmp = 0;
+ uint16_t freesize = 0;
+ uint32_t taddr;
+
+ CHECK_SOCKNUM();
+ switch(getSn_MR(sn) & 0x0F)
+ {
+ case Sn_MR_UDP:
+ case Sn_MR_MACRAW:
+// break;
+// #if ( _WIZCHIP_ < 5200 )
+ case Sn_MR_IPRAW:
+ break;
+// #endif
+ default:
+ return SOCKERR_SOCKMODE;
+ }
+ CHECK_SOCKDATA();
+ //M20140501 : For avoiding fatal error on memory align mismatched
+ //if(*((uint32_t*)addr) == 0) return SOCKERR_IPINVALID;
+ //{
+ //uint32_t taddr;
+ taddr = ((uint32_t)addr[0]) & 0x000000FF;
+ taddr = (taddr << 8) + ((uint32_t)addr[1] & 0x000000FF);
+ taddr = (taddr << 8) + ((uint32_t)addr[2] & 0x000000FF);
+ taddr = (taddr << 8) + ((uint32_t)addr[3] & 0x000000FF);
+ //}
+ //
+ //if(*((uint32_t*)addr) == 0) return SOCKERR_IPINVALID;
+ if((taddr == 0) && (getSn_MR(sn)&Sn_MR_MACRAW != Sn_MR_MACRAW)) return SOCKERR_IPINVALID;
+ if((port == 0) && (getSn_MR(sn)&Sn_MR_MACRAW != Sn_MR_MACRAW)) return SOCKERR_PORTZERO;
+ tmp = getSn_SR(sn);
+//#if ( _WIZCHIP_ < 5200 )
+ if(tmp != SOCK_MACRAW && tmp != SOCK_UDP && tmp != SOCK_IPRAW) return SOCKERR_SOCKSTATUS;
+//#else
+// if(tmp != SOCK_MACRAW && tmp != SOCK_UDP) return SOCKERR_SOCKSTATUS;
+//#endif
+
+ setSn_DIPR(sn,addr);
+ setSn_DPORT(sn,port);
+ freesize = getSn_TxMAX(sn);
+ if (len > freesize) len = freesize; // check size not to exceed MAX size.
+ while(1)
+ {
+ freesize = getSn_TX_FSR(sn);
+ if(getSn_SR(sn) == SOCK_CLOSED) return SOCKERR_SOCKCLOSED;
+ if( (sock_io_mode & (1< freesize) ) return SOCK_BUSY;
+ if(len <= freesize) break;
+ };
+ wiz_send_data(sn, buf, len);
+
+ #if _WIZCHIP_ < 5500 //M20150401 : for WIZCHIP Errata #4, #5 (ARP errata)
+ getSIPR((uint8_t*)&taddr);
+ if(taddr == 0)
+ {
+ getSUBR((uint8_t*)&taddr);
+ setSUBR((uint8_t*)"\x00\x00\x00\x00");
+ }
+ else taddr = 0;
+ #endif
+
+//A20150601 : For W5300
+#if _WIZCHIP_ == 5300
+ setSn_TX_WRSR(sn, len);
+#endif
+//
+ setSn_CR(sn,Sn_CR_SEND);
+ /* wait to process the command... */
+ while(getSn_CR(sn));
+ while(1)
+ {
+ tmp = getSn_IR(sn);
+ if(tmp & Sn_IR_SENDOK)
+ {
+ setSn_IR(sn, Sn_IR_SENDOK);
+ break;
+ }
+ //M:20131104
+ //else if(tmp & Sn_IR_TIMEOUT) return SOCKERR_TIMEOUT;
+ else if(tmp & Sn_IR_TIMEOUT)
+ {
+ setSn_IR(sn, Sn_IR_TIMEOUT);
+ //M20150409 : Fixed the lost of sign bits by type casting.
+ //len = (uint16_t)SOCKERR_TIMEOUT;
+ //break;
+ #if _WIZCHIP_ < 5500 //M20150401 : for WIZCHIP Errata #4, #5 (ARP errata)
+ if(taddr) setSUBR((uint8_t*)&taddr);
+ #endif
+ return SOCKERR_TIMEOUT;
+ }
+ ////////////
+ }
+ #if _WIZCHIP_ < 5500 //M20150401 : for WIZCHIP Errata #4, #5 (ARP errata)
+ if(taddr) setSUBR((uint8_t*)&taddr);
+ #endif
+ //M20150409 : Explicit Type Casting
+ //return len;
+ return (int32_t)len;
+}
+
+
+
+int32_t recvfrom(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t *port)
+{
+//M20150601 : For W5300
+#if _WIZCHIP_ == 5300
+ uint16_t mr;
+ uint16_t mr1;
+#else
+ uint8_t mr;
+#endif
+//
+ uint8_t head[8];
+ uint16_t pack_len=0;
+
+ CHECK_SOCKNUM();
+ //CHECK_SOCKMODE(Sn_MR_UDP);
+//A20150601
+#if _WIZCHIP_ == 5300
+ mr1 = getMR();
+#endif
+
+ switch((mr=getSn_MR(sn)) & 0x0F)
+ {
+ case Sn_MR_UDP:
+ case Sn_MR_IPRAW:
+ case Sn_MR_MACRAW:
+ break;
+ #if ( _WIZCHIP_ < 5200 )
+ case Sn_MR_PPPoE:
+ break;
+ #endif
+ default:
+ return SOCKERR_SOCKMODE;
+ }
+ CHECK_SOCKDATA();
+ if(sock_remained_size[sn] == 0)
+ {
+ while(1)
+ {
+ pack_len = getSn_RX_RSR(sn);
+ if(getSn_SR(sn) == SOCK_CLOSED) return SOCKERR_SOCKCLOSED;
+ if( (sock_io_mode & (1< 1514)
+ {
+ close(sn);
+ return SOCKFATAL_PACKLEN;
+ }
+ sock_pack_info[sn] = PACK_FIRST;
+ }
+ if(len < sock_remained_size[sn]) pack_len = len;
+ else pack_len = sock_remained_size[sn];
+ wiz_recv_data(sn,buf,pack_len);
+ break;
+ //#if ( _WIZCHIP_ < 5200 )
+ case Sn_MR_IPRAW:
+ if(sock_remained_size[sn] == 0)
+ {
+ wiz_recv_data(sn, head, 6);
+ setSn_CR(sn,Sn_CR_RECV);
+ while(getSn_CR(sn));
+ addr[0] = head[0];
+ addr[1] = head[1];
+ addr[2] = head[2];
+ addr[3] = head[3];
+ sock_remained_size[sn] = head[4];
+ //M20150401 : For Typing Error
+ //sock_remaiend_size[sn] = (sock_remained_size[sn] << 8) + head[5];
+ sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[5];
+ sock_pack_info[sn] = PACK_FIRST;
+ }
+ //
+ // Need to packet length check
+ //
+ if(len < sock_remained_size[sn]) pack_len = len;
+ else pack_len = sock_remained_size[sn];
+ wiz_recv_data(sn, buf, pack_len); // data copy.
+ break;
+ //#endif
+ default:
+ wiz_recv_ignore(sn, pack_len); // data copy.
+ sock_remained_size[sn] = pack_len;
+ break;
+ }
+ setSn_CR(sn,Sn_CR_RECV);
+ /* wait to process the command... */
+ while(getSn_CR(sn)) ;
+ sock_remained_size[sn] -= pack_len;
+ //M20150601 :
+ //if(sock_remained_size[sn] != 0) sock_pack_info[sn] |= 0x01;
+ if(sock_remained_size[sn] != 0)
+ {
+ sock_pack_info[sn] |= PACK_REMAINED;
+ #if _WIZCHIP_ == 5300
+ if(pack_len & 0x01) sock_pack_info[sn] |= PACK_FIFOBYTE;
+ #endif
+ }
+ else sock_pack_info[sn] = PACK_COMPLETED;
+#if _WIZCHIP_ == 5300
+ pack_len = len;
+#endif
+ //
+ //M20150409 : Explicit Type Casting
+ //return pack_len;
+ return (int32_t)pack_len;
+}
+
+
+int8_t ctlsocket(uint8_t sn, ctlsock_type cstype, void* arg)
+{
+ uint8_t tmp = 0;
+ CHECK_SOCKNUM();
+ switch(cstype)
+ {
+ case CS_SET_IOMODE:
+ tmp = *((uint8_t*)arg);
+ if(tmp == SOCK_IO_NONBLOCK) sock_io_mode |= (1< explict type casting
+ //*((uint8_t*)arg) = (sock_io_mode >> sn) & 0x0001;
+ *((uint8_t*)arg) = (uint8_t)((sock_io_mode >> sn) & 0x0001);
+ //
+ break;
+ case CS_GET_MAXTXBUF:
+ *((uint16_t*)arg) = getSn_TxMAX(sn);
+ break;
+ case CS_GET_MAXRXBUF:
+ *((uint16_t*)arg) = getSn_RxMAX(sn);
+ break;
+ case CS_CLR_INTERRUPT:
+ if( (*(uint8_t*)arg) > SIK_ALL) return SOCKERR_ARG;
+ setSn_IR(sn,*(uint8_t*)arg);
+ break;
+ case CS_GET_INTERRUPT:
+ *((uint8_t*)arg) = getSn_IR(sn);
+ break;
+ #if _WIZCHIP_ != 5100
+ case CS_SET_INTMASK:
+ if( (*(uint8_t*)arg) > SIK_ALL) return SOCKERR_ARG;
+ setSn_IMR(sn,*(uint8_t*)arg);
+ break;
+ case CS_GET_INTMASK:
+ *((uint8_t*)arg) = getSn_IMR(sn);
+ break;
+ #endif
+ default:
+ return SOCKERR_ARG;
+ }
+ return SOCK_OK;
+}
+
+int8_t setsockopt(uint8_t sn, sockopt_type sotype, void* arg)
+{
+ // M20131220 : Remove warning
+ //uint8_t tmp;
+ CHECK_SOCKNUM();
+ switch(sotype)
+ {
+ case SO_TTL:
+ setSn_TTL(sn,*(uint8_t*)arg);
+ break;
+ case SO_TOS:
+ setSn_TOS(sn,*(uint8_t*)arg);
+ break;
+ case SO_MSS:
+ setSn_MSSR(sn,*(uint16_t*)arg);
+ break;
+ case SO_DESTIP:
+ setSn_DIPR(sn, (uint8_t*)arg);
+ break;
+ case SO_DESTPORT:
+ setSn_DPORT(sn, *(uint16_t*)arg);
+ break;
+#if _WIZCHIP_ != 5100
+ case SO_KEEPALIVESEND:
+ CHECK_SOCKMODE(Sn_MR_TCP);
+ #if _WIZCHIP_ > 5200
+ if(getSn_KPALVTR(sn) != 0) return SOCKERR_SOCKOPT;
+ #endif
+ setSn_CR(sn,Sn_CR_SEND_KEEP);
+ while(getSn_CR(sn) != 0)
+ {
+ // M20131220
+ //if ((tmp = getSn_IR(sn)) & Sn_IR_TIMEOUT)
+ if (getSn_IR(sn) & Sn_IR_TIMEOUT)
+ {
+ setSn_IR(sn, Sn_IR_TIMEOUT);
+ return SOCKERR_TIMEOUT;
+ }
+ }
+ break;
+ #if _WIZCHIP_ > 5200
+ case SO_KEEPALIVEAUTO:
+ CHECK_SOCKMODE(Sn_MR_TCP);
+ setSn_KPALVTR(sn,*(uint8_t*)arg);
+ break;
+ #endif
+#endif
+ default:
+ return SOCKERR_ARG;
+ }
+ return SOCK_OK;
+}
+
+int8_t getsockopt(uint8_t sn, sockopt_type sotype, void* arg)
+{
+ CHECK_SOCKNUM();
+ switch(sotype)
+ {
+ case SO_FLAG:
+ *(uint8_t*)arg = getSn_MR(sn) & 0xF0;
+ break;
+ case SO_TTL:
+ *(uint8_t*) arg = getSn_TTL(sn);
+ break;
+ case SO_TOS:
+ *(uint8_t*) arg = getSn_TOS(sn);
+ break;
+ case SO_MSS:
+ *(uint16_t*) arg = getSn_MSSR(sn);
+ break;
+ case SO_DESTIP:
+ getSn_DIPR(sn, (uint8_t*)arg);
+ break;
+ case SO_DESTPORT:
+ *(uint16_t*) arg = getSn_DPORT(sn);
+ break;
+ #if _WIZCHIP_ > 5200
+ case SO_KEEPALIVEAUTO:
+ CHECK_SOCKMODE(Sn_MR_TCP);
+ *(uint16_t*) arg = getSn_KPALVTR(sn);
+ break;
+ #endif
+ case SO_SENDBUF:
+ *(uint16_t*) arg = getSn_TX_FSR(sn);
+ break;
+ case SO_RECVBUF:
+ *(uint16_t*) arg = getSn_RX_RSR(sn);
+ break;
+ case SO_STATUS:
+ *(uint8_t*) arg = getSn_SR(sn);
+ break;
+ case SO_REMAINSIZE:
+ if(getSn_MR(sn) == Sn_MR_TCP)
+ *(uint16_t*)arg = getSn_RX_RSR(sn);
+ else
+ *(uint16_t*)arg = sock_remained_size[sn];
+ break;
+ case SO_PACKINFO:
+ //CHECK_SOCKMODE(Sn_MR_TCP);
+#if _WIZCHIP_ != 5300
+ if((getSn_MR(sn) == Sn_MR_TCP))
+ return SOCKERR_SOCKMODE;
+#endif
+ *(uint8_t*)arg = sock_pack_info[sn];
+ break;
+ default:
+ return SOCKERR_SOCKOPT;
+ }
+ return SOCK_OK;
+}
diff --git a/Libraries/ioLibrary_Driver/Ethernet/socket.h b/Libraries/ioLibrary_Driver/Ethernet/socket.h
new file mode 100644
index 0000000..0129adb
--- /dev/null
+++ b/Libraries/ioLibrary_Driver/Ethernet/socket.h
@@ -0,0 +1,482 @@
+//*****************************************************************************
+//
+//! \file socket.h
+//! \brief SOCKET APIs Header file.
+//! \details SOCKET APIs like as berkeley socket api.
+//! \version 1.0.2
+//! \date 2013/10/21
+//! \par Revision history
+//! <2015/02/05> Notice
+//! The version history is not updated after this point.
+//! Download the latest version directly from GitHub. Please visit the our GitHub repository for ioLibrary.
+//! >> https://github.com/Wiznet/ioLibrary_Driver
+//! <2014/05/01> V1.0.2. Refer to M20140501
+//! 1. Modify the comment : SO_REMAINED -> PACK_REMAINED
+//! 2. Add the comment as zero byte udp data reception in getsockopt().
+//! <2013/10/21> 1st Release
+//! \author MidnightCow
+//! \copyright
+//!
+//! Copyright (c) 2013, WIZnet Co., LTD.
+//! All rights reserved.
+//!
+//! Redistribution and use in source and binary forms, with or without
+//! modification, are permitted provided that the following conditions
+//! are met:
+//!
+//! * Redistributions of source code must retain the above copyright
+//! notice, this list of conditions and the following disclaimer.
+//! * Redistributions in binary form must reproduce the above copyright
+//! notice, this list of conditions and the following disclaimer in the
+//! documentation and/or other materials provided with the distribution.
+//! * Neither the name of the nor the names of its
+//! contributors may be used to endorse or promote products derived
+//! from this software without specific prior written permission.
+//!
+//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+//! THE POSSIBILITY OF SUCH DAMAGE.
+//
+//*****************************************************************************
+/**
+ * @defgroup WIZnet_socket_APIs 1. WIZnet socket APIs
+ * @brief WIZnet socket APIs are based on Berkeley socket APIs, thus it has much similar name and interface.
+ * But there is a little bit of difference.
+ * @details
+ * Comparison between WIZnet and Berkeley SOCKET APIs
+ *
+ *
API
WIZnet
Berkeley
+ *
socket()
O
O
+ *
bind()
X
O
+ *
listen()
O
O
+ *
connect()
O
O
+ *
accept()
X
O
+ *
recv()
O
O
+ *
send()
O
O
+ *
recvfrom()
O
O
+ *
sendto()
O
O
+ *
closesocket()
O close() & disconnect()
O
+ *
+ * There are @b bind() and @b accept() functions in @b Berkeley SOCKET API but,
+ * not in @b WIZnet SOCKET API. Because socket() of WIZnet is not only creating a SOCKET but also binding a local port number,
+ * and listen() of WIZnet is not only listening to connection request from client but also accepting the connection request. \n
+ * When you program "TCP SERVER" with Berkeley SOCKET API, you can use only one listen port.
+ * When the listen SOCKET accepts a connection request from a client, it keeps listening.
+ * After accepting the connection request, a new SOCKET is created and the new SOCKET is used in communication with the client. \n
+ * Following figure shows network flow diagram by Berkeley SOCKET API.
+ * @image html Berkeley_SOCKET.jpg ""
+ * But, When you program "TCP SERVER" with WIZnet SOCKET API, you can use as many as 8 listen SOCKET with same port number. \n
+ * Because there's no accept() in WIZnet SOCKET APIs, when the listen SOCKET accepts a connection request from a client,
+ * it is changed in order to communicate with the client.
+ * And the changed SOCKET is not listening any more and is dedicated for communicating with the client. \n
+ * If there're many listen SOCKET with same listen port number and a client requests a connection,
+ * the SOCKET which has the smallest SOCKET number accepts the request and is changed as communication SOCKET. \n
+ * Following figure shows network flow diagram by WIZnet SOCKET API.
+ * @image html WIZnet_SOCKET.jpg ""
+ */
+#ifndef _SOCKET_H_
+#define _SOCKET_H_
+
+#include "wizchip_conf.h"
+
+#define SOCKET uint8_t ///< SOCKET type define for legacy driver
+
+#define SOCK_OK 1 ///< Result is OK about socket process.
+#define SOCK_BUSY 0 ///< Socket is busy on processing the operation. Valid only Non-block IO Mode.
+#define SOCK_FATAL -1000 ///< Result is fatal error about socket process.
+
+#define SOCK_ERROR 0
+#define SOCKERR_SOCKNUM (SOCK_ERROR - 1) ///< Invalid socket number
+#define SOCKERR_SOCKOPT (SOCK_ERROR - 2) ///< Invalid socket option
+#define SOCKERR_SOCKINIT (SOCK_ERROR - 3) ///< Socket is not initialized or SIPR is Zero IP address when Sn_MR_TCP
+#define SOCKERR_SOCKCLOSED (SOCK_ERROR - 4) ///< Socket unexpectedly closed.
+#define SOCKERR_SOCKMODE (SOCK_ERROR - 5) ///< Invalid socket mode for socket operation.
+#define SOCKERR_SOCKFLAG (SOCK_ERROR - 6) ///< Invalid socket flag
+#define SOCKERR_SOCKSTATUS (SOCK_ERROR - 7) ///< Invalid socket status for socket operation.
+#define SOCKERR_ARG (SOCK_ERROR - 10) ///< Invalid argument.
+#define SOCKERR_PORTZERO (SOCK_ERROR - 11) ///< Port number is zero
+#define SOCKERR_IPINVALID (SOCK_ERROR - 12) ///< Invalid IP address
+#define SOCKERR_TIMEOUT (SOCK_ERROR - 13) ///< Timeout occurred
+#define SOCKERR_DATALEN (SOCK_ERROR - 14) ///< Data length is zero or greater than buffer max size.
+#define SOCKERR_BUFFER (SOCK_ERROR - 15) ///< Socket buffer is not enough for data communication.
+
+#define SOCKFATAL_PACKLEN (SOCK_FATAL - 1) ///< Invalid packet length. Fatal Error.
+
+/*
+ * SOCKET FLAG
+ */
+#define SF_ETHER_OWN (Sn_MR_MFEN) ///< In @ref Sn_MR_MACRAW, Receive only the packet as broadcast, multicast and own packet
+#define SF_IGMP_VER2 (Sn_MR_MC) ///< In @ref Sn_MR_UDP with \ref SF_MULTI_ENABLE, Select IGMP version 2.
+#define SF_TCP_NODELAY (Sn_MR_ND) ///< In @ref Sn_MR_TCP, Use to nodelayed ack.
+#define SF_MULTI_ENABLE (Sn_MR_MULTI) ///< In @ref Sn_MR_UDP, Enable multicast mode.
+
+#if _WIZCHIP_ == 5500
+ #define SF_BROAD_BLOCK (Sn_MR_BCASTB) ///< In @ref Sn_MR_UDP or @ref Sn_MR_MACRAW, Block broadcast packet. Valid only in W5500
+ #define SF_MULTI_BLOCK (Sn_MR_MMB) ///< In @ref Sn_MR_MACRAW, Block multicast packet. Valid only in W5500
+ #define SF_IPv6_BLOCK (Sn_MR_MIP6B) ///< In @ref Sn_MR_MACRAW, Block IPv6 packet. Valid only in W5500
+ #define SF_UNI_BLOCK (Sn_MR_UCASTB) ///< In @ref Sn_MR_UDP with \ref SF_MULTI_ENABLE. Valid only in W5500
+#endif
+
+//A201505 : For W5300
+#if _WIZCHIP_ == 5300
+ #define SF_TCP_ALIGN 0x02 ///< Valid only \ref Sn_MR_TCP and W5300, refer to \ref Sn_MR_ALIGN
+#endif
+
+#define SF_IO_NONBLOCK 0x01 ///< Socket nonblock io mode. It used parameter in \ref socket().
+
+/*
+ * UDP & MACRAW Packet Infomation
+ */
+#define PACK_FIRST 0x80 ///< In Non-TCP packet, It indicates to start receiving a packet. (When W5300, This flag can be applied)
+#define PACK_REMAINED 0x01 ///< In Non-TCP packet, It indicates to remain a packet to be received. (When W5300, This flag can be applied)
+#define PACK_COMPLETED 0x00 ///< In Non-TCP packet, It indicates to complete to receive a packet. (When W5300, This flag can be applied)
+//A20150601 : For Integrating with W5300
+#define PACK_FIFOBYTE 0x02 ///< Valid only W5300, It indicate to have read already the Sn_RX_FIFOR.
+//
+
+/**
+ * @ingroup WIZnet_socket_APIs
+ * @brief Open a socket.
+ * @details Initializes the socket with 'sn' passed as parameter and open.
+ *
+ * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param protocol Protocol type to operate such as TCP, UDP and MACRAW.
+ * @param port Port number to be bined.
+ * @param flag Socket flags as \ref SF_ETHER_OWN, \ref SF_IGMP_VER2, \ref SF_TCP_NODELAY, \ref SF_MULTI_ENABLE, \ref SF_IO_NONBLOCK and so on.\n
+ * Valid flags only in W5500 : @ref SF_BROAD_BLOCK, @ref SF_MULTI_BLOCK, @ref SF_IPv6_BLOCK, and @ref SF_UNI_BLOCK.
+ * @sa Sn_MR
+ *
+ * @return @b Success : The socket number @b 'sn' passed as parameter\n
+ * @b Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number\n
+ * @ref SOCKERR_SOCKMODE - Not support socket mode as TCP, UDP, and so on. \n
+ * @ref SOCKERR_SOCKFLAG - Invaild socket flag.
+ */
+int8_t socket(uint8_t sn, uint8_t protocol, uint16_t port, uint8_t flag);
+
+/**
+ * @ingroup WIZnet_socket_APIs
+ * @brief Close a socket.
+ * @details It closes the socket with @b'sn' passed as parameter.
+ *
+ * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ *
+ * @return @b Success : @ref SOCK_OK \n
+ * @b Fail : @ref SOCKERR_SOCKNUM - Invalid socket number
+ */
+int8_t close(uint8_t sn);
+
+/**
+ * @ingroup WIZnet_socket_APIs
+ * @brief Listen to a connection request from a client.
+ * @details It is listening to a connection request from a client.
+ * If connection request is accepted successfully, the connection is established. Socket sn is used in passive(server) mode.
+ *
+ * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return @b Success : @ref SOCK_OK \n
+ * @b Fail :\n @ref SOCKERR_SOCKINIT - Socket is not initialized \n
+ * @ref SOCKERR_SOCKCLOSED - Socket closed unexpectedly.
+ */
+int8_t listen(uint8_t sn);
+
+/**
+ * @ingroup WIZnet_socket_APIs
+ * @brief Try to connect a server.
+ * @details It requests connection to the server with destination IP address and port number passed as parameter.\n
+ * @note It is valid only in TCP client mode.
+ * In block io mode, it does not return until connection is completed.
+ * In Non-block io mode, it return @ref SOCK_BUSY immediately.
+ *
+ * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param addr Pointer variable of destination IP address. It should be allocated 4 bytes.
+ * @param port Destination port number.
+ *
+ * @return @b Success : @ref SOCK_OK \n
+ * @b Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number\n
+ * @ref SOCKERR_SOCKMODE - Invalid socket mode\n
+ * @ref SOCKERR_SOCKINIT - Socket is not initialized\n
+ * @ref SOCKERR_IPINVALID - Wrong server IP address\n
+ * @ref SOCKERR_PORTZERO - Server port zero\n
+ * @ref SOCKERR_TIMEOUT - Timeout occurred during request connection\n
+ * @ref SOCK_BUSY - In non-block io mode, it returned immediately\n
+ */
+int8_t connect(uint8_t sn, uint8_t * addr, uint16_t port);
+
+/**
+ * @ingroup WIZnet_socket_APIs
+ * @brief Try to disconnect a connection socket.
+ * @details It sends request message to disconnect the TCP socket 'sn' passed as parameter to the server or client.
+ * @note It is valid only in TCP server or client mode. \n
+ * In block io mode, it does not return until disconnection is completed. \n
+ * In Non-block io mode, it return @ref SOCK_BUSY immediately. \n
+
+ * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @return @b Success : @ref SOCK_OK \n
+ * @b Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number \n
+ * @ref SOCKERR_SOCKMODE - Invalid operation in the socket \n
+ * @ref SOCKERR_TIMEOUT - Timeout occurred \n
+ * @ref SOCK_BUSY - Socket is busy.
+ */
+int8_t disconnect(uint8_t sn);
+
+/**
+ * @ingroup WIZnet_socket_APIs
+ * @brief Send data to the connected peer in TCP socket.
+ * @details It is used to send outgoing data to the connected socket.
+ * @note It is valid only in TCP server or client mode. It can't send data greater than socket buffer size. \n
+ * In block io mode, It doesn't return until data send is completed - socket buffer size is greater than data. \n
+ * In non-block io mode, It return @ref SOCK_BUSY immediately when socket buffer is not enough. \n
+ * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param buf Pointer buffer containing data to be sent.
+ * @param len The byte length of data in buf.
+ * @return @b Success : The sent data size \n
+ * @b Fail : \n @ref SOCKERR_SOCKSTATUS - Invalid socket status for socket operation \n
+ * @ref SOCKERR_TIMEOUT - Timeout occurred \n
+ * @ref SOCKERR_SOCKMODE - Invalid operation in the socket \n
+ * @ref SOCKERR_SOCKNUM - Invalid socket number \n
+ * @ref SOCKERR_DATALEN - zero data length \n
+ * @ref SOCK_BUSY - Socket is busy.
+ */
+int32_t send(uint8_t sn, uint8_t * buf, uint16_t len);
+
+/**
+ * @ingroup WIZnet_socket_APIs
+ * @brief Receive data from the connected peer.
+ * @details It is used to read incoming data from the connected socket.\n
+ * It waits for data as much as the application wants to receive.
+ * @note It is valid only in TCP server or client mode. It can't receive data greater than socket buffer size. \n
+ * In block io mode, it doesn't return until data reception is completed - data is filled as len in socket buffer. \n
+ * In non-block io mode, it return @ref SOCK_BUSY immediately when len is greater than data size in socket buffer. \n
+ *
+ * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param buf Pointer buffer to read incoming data.
+ * @param len The max data length of data in buf.
+ * @return @b Success : The real received data size \n
+ * @b Fail :\n
+ * @ref SOCKERR_SOCKSTATUS - Invalid socket status for socket operation \n
+ * @ref SOCKERR_SOCKMODE - Invalid operation in the socket \n
+ * @ref SOCKERR_SOCKNUM - Invalid socket number \n
+ * @ref SOCKERR_DATALEN - zero data length \n
+ * @ref SOCK_BUSY - Socket is busy.
+ */
+int32_t recv(uint8_t sn, uint8_t * buf, uint16_t len);
+
+/**
+ * @ingroup WIZnet_socket_APIs
+ * @brief Sends datagram to the peer with destination IP address and port number passed as parameter.
+ * @details It sends datagram of UDP or MACRAW to the peer with destination IP address and port number passed as parameter.\n
+ * Even if the connectionless socket has been previously connected to a specific address,
+ * the address and port number parameters override the destination address for that particular datagram only.
+ * @note In block io mode, It doesn't return until data send is completed - socket buffer size is greater than len.
+ * In non-block io mode, It return @ref SOCK_BUSY immediately when socket buffer is not enough.
+ *
+ * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param buf Pointer buffer to send outgoing data.
+ * @param len The byte length of data in buf.
+ * @param addr Pointer variable of destination IP address. It should be allocated 4 bytes.
+ * @param port Destination port number.
+ *
+ * @return @b Success : The sent data size \n
+ * @b Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number \n
+ * @ref SOCKERR_SOCKMODE - Invalid operation in the socket \n
+ * @ref SOCKERR_SOCKSTATUS - Invalid socket status for socket operation \n
+ * @ref SOCKERR_DATALEN - zero data length \n
+ * @ref SOCKERR_IPINVALID - Wrong server IP address\n
+ * @ref SOCKERR_PORTZERO - Server port zero\n
+ * @ref SOCKERR_SOCKCLOSED - Socket unexpectedly closed \n
+ * @ref SOCKERR_TIMEOUT - Timeout occurred \n
+ * @ref SOCK_BUSY - Socket is busy.
+ */
+int32_t sendto(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t port);
+
+/**
+ * @ingroup WIZnet_socket_APIs
+ * @brief Receive datagram of UDP or MACRAW
+ * @details This function is an application I/F function which is used to receive the data in other then TCP mode. \n
+ * This function is used to receive UDP and MAC_RAW mode, and handle the header as well.
+ * This function can divide to received the packet data.
+ * On the MACRAW SOCKET, the addr and port parameters are ignored.
+ * @note In block io mode, it doesn't return until data reception is completed - data is filled as len in socket buffer
+ * In non-block io mode, it return @ref SOCK_BUSY immediately when len is greater than data size in socket buffer.
+ *
+ * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_.
+ * @param buf Pointer buffer to read incoming data.
+ * @param len The max data length of data in buf.
+ * When the received packet size <= len, receives data as packet sized.
+ * When others, receives data as len.
+ * @param addr Pointer variable of destination IP address. It should be allocated 4 bytes.
+ * It is valid only when the first call recvfrom for receiving the packet.
+ * When it is valid, @ref packinfo[7] should be set as '1' after call @ref getsockopt(sn, SO_PACKINFO, &packinfo).
+ * @param port Pointer variable of destination port number.
+ * It is valid only when the first call recvform for receiving the packet.
+* When it is valid, @ref packinfo[7] should be set as '1' after call @ref getsockopt(sn, SO_PACKINFO, &packinfo).
+ *
+ * @return @b Success : This function return real received data size for success.\n
+ * @b Fail : @ref SOCKERR_DATALEN - zero data length \n
+ * @ref SOCKERR_SOCKMODE - Invalid operation in the socket \n
+ * @ref SOCKERR_SOCKNUM - Invalid socket number \n
+ * @ref SOCKBUSY - Socket is busy.
+ */
+int32_t recvfrom(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t *port);
+
+
+/////////////////////////////
+// SOCKET CONTROL & OPTION //
+/////////////////////////////
+#define SOCK_IO_BLOCK 0 ///< Socket Block IO Mode in @ref setsockopt().
+#define SOCK_IO_NONBLOCK 1 ///< Socket Non-block IO Mode in @ref setsockopt().
+
+/**
+ * @defgroup DATA_TYPE DATA TYPE
+ */
+
+/**
+ * @ingroup DATA_TYPE
+ * @brief The kind of Socket Interrupt.
+ * @sa Sn_IR, Sn_IMR, setSn_IR(), getSn_IR(), setSn_IMR(), getSn_IMR()
+ */
+typedef enum
+{
+ SIK_CONNECTED = (1 << 0), ///< connected
+ SIK_DISCONNECTED = (1 << 1), ///< disconnected
+ SIK_RECEIVED = (1 << 2), ///< data received
+ SIK_TIMEOUT = (1 << 3), ///< timeout occurred
+ SIK_SENT = (1 << 4), ///< send ok
+ //M20150410 : Remove the comma of last member
+ //SIK_ALL = 0x1F, ///< all interrupt
+ SIK_ALL = 0x1F ///< all interrupt
+}sockint_kind;
+
+/**
+ * @ingroup DATA_TYPE
+ * @brief The type of @ref ctlsocket().
+ */
+typedef enum
+{
+ CS_SET_IOMODE, ///< set socket IO mode with @ref SOCK_IO_BLOCK or @ref SOCK_IO_NONBLOCK
+ CS_GET_IOMODE, ///< get socket IO mode
+ CS_GET_MAXTXBUF, ///< get the size of socket buffer allocated in TX memory
+ CS_GET_MAXRXBUF, ///< get the size of socket buffer allocated in RX memory
+ CS_CLR_INTERRUPT, ///< clear the interrupt of socket with @ref sockint_kind
+ CS_GET_INTERRUPT, ///< get the socket interrupt. refer to @ref sockint_kind
+#if _WIZCHIP_ > 5100
+ CS_SET_INTMASK, ///< set the interrupt mask of socket with @ref sockint_kind, Not supported in W5100
+ CS_GET_INTMASK ///< get the masked interrupt of socket. refer to @ref sockint_kind, Not supported in W5100
+#endif
+}ctlsock_type;
+
+
+/**
+ * @ingroup DATA_TYPE
+ * @brief The type of socket option in @ref setsockopt() or @ref getsockopt()
+ */
+typedef enum
+{
+ SO_FLAG, ///< Valid only in getsockopt(), For set flag of socket refer to flag in @ref socket().
+ SO_TTL, ///< Set TTL. @ref Sn_TTL ( @ref setSn_TTL(), @ref getSn_TTL() )
+ SO_TOS, ///< Set TOS. @ref Sn_TOS ( @ref setSn_TOS(), @ref getSn_TOS() )
+ SO_MSS, ///< Set MSS. @ref Sn_MSSR ( @ref setSn_MSSR(), @ref getSn_MSSR() )
+ SO_DESTIP, ///< Set the destination IP address. @ref Sn_DIPR ( @ref setSn_DIPR(), @ref getSn_DIPR() )
+ SO_DESTPORT, ///< Set the destination Port number. @ref Sn_DPORT ( @ref setSn_DPORT(), @ref getSn_DPORT() )
+#if _WIZCHIP_ != 5100
+ SO_KEEPALIVESEND, ///< Valid only in setsockopt. Manually send keep-alive packet in TCP mode, Not supported in W5100
+ #if _WIZCHIP_ > 5200
+ SO_KEEPALIVEAUTO, ///< Set/Get keep-alive auto transmission timer in TCP mode, Not supported in W5100, W5200
+ #endif
+#endif
+ SO_SENDBUF, ///< Valid only in getsockopt. Get the free data size of Socekt TX buffer. @ref Sn_TX_FSR, @ref getSn_TX_FSR()
+ SO_RECVBUF, ///< Valid only in getsockopt. Get the received data size in socket RX buffer. @ref Sn_RX_RSR, @ref getSn_RX_RSR()
+ SO_STATUS, ///< Valid only in getsockopt. Get the socket status. @ref Sn_SR, @ref getSn_SR()
+ SO_REMAINSIZE, ///< Valid only in getsockopt. Get the remained packet size in other then TCP mode.
+ SO_PACKINFO ///< Valid only in getsockopt. Get the packet information as @ref PACK_FIRST, @ref PACK_REMAINED, and @ref PACK_COMPLETED in other then TCP mode.
+}sockopt_type;
+
+/**
+ * @ingroup WIZnet_socket_APIs
+ * @brief Control socket.
+ * @details Control IO mode, Interrupt & Mask of socket and get the socket buffer information.
+ * Refer to @ref ctlsock_type.
+ * @param sn socket number
+ * @param cstype type of control socket. refer to @ref ctlsock_type.
+ * @param arg Data type and value is determined according to @ref ctlsock_type. \n
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F10x_CONF_H
+#define __STM32F10x_CONF_H
+
+/* Includes ------------------------------------------------------------------*/
+/* Uncomment/Comment the line below to enable/disable peripheral header file inclusion */
+#include "stm32f10x_adc.h"
+#include "stm32f10x_bkp.h"
+#include "stm32f10x_can.h"
+#include "stm32f10x_cec.h"
+#include "stm32f10x_crc.h"
+#include "stm32f10x_dac.h"
+#include "stm32f10x_dbgmcu.h"
+#include "stm32f10x_dma.h"
+#include "stm32f10x_exti.h"
+#include "stm32f10x_flash.h"
+#include "stm32f10x_fsmc.h"
+#include "stm32f10x_gpio.h"
+#include "stm32f10x_i2c.h"
+#include "stm32f10x_iwdg.h"
+#include "stm32f10x_pwr.h"
+#include "stm32f10x_rcc.h"
+#include "stm32f10x_rtc.h"
+#include "stm32f10x_sdio.h"
+#include "stm32f10x_spi.h"
+#include "stm32f10x_tim.h"
+#include "stm32f10x_usart.h"
+#include "stm32f10x_wwdg.h"
+#include "misc.h" /* High level functions for NVIC and SysTick (add-on to CMSIS functions) */
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+/* Uncomment the line below to expanse the "assert_param" macro in the
+ Standard Peripheral Library drivers code */
+/* #define USE_FULL_ASSERT 1 */
+
+/* Exported macro ------------------------------------------------------------*/
+#ifdef USE_FULL_ASSERT
+
+/**
+ * @brief The assert_param macro is used for function's parameters check.
+ * @param expr: If expr is false, it calls assert_failed function which reports
+ * the name of the source file and the source line number of the call
+ * that failed. If expr is true, it returns no value.
+ * @retval None
+ */
+ #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))
+/* Exported functions ------------------------------------------------------- */
+ void assert_failed(uint8_t* file, uint32_t line);
+#else
+ #define assert_param(expr) ((void)0)
+#endif /* USE_FULL_ASSERT */
+
+#endif /* __STM32F10x_CONF_H */
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
diff --git a/src/system_stm32f10x.c b/src/system_stm32f10x.c
new file mode 100644
index 0000000..7e23e0f
--- /dev/null
+++ b/src/system_stm32f10x.c
@@ -0,0 +1,1102 @@
+/**
+ ******************************************************************************
+ * @file system_stm32f10x.c
+ * @author MCD Application Team
+ * @version V3.6.1
+ * @date 09-March-2012
+ * @brief CMSIS Cortex-M3 Device Peripheral Access Layer System Source File.
+ *
+ * 1. This file provides two functions and one global variable to be called from
+ * user application:
+ * - SystemInit(): Setups the system clock (System clock source, PLL Multiplier
+ * factors, AHB/APBx prescalers and Flash settings).
+ * This function is called at startup just after reset and
+ * before branch to main program. This call is made inside
+ * the "startup_stm32f10x_xx.s" file.
+ *
+ * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
+ * by the user application to setup the SysTick
+ * timer or configure other parameters.
+ *
+ * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
+ * be called whenever the core clock is changed
+ * during program execution.
+ *
+ * 2. After each device reset the HSI (8 MHz) is used as system clock source.
+ * Then SystemInit() function is called, in "startup_stm32f10x_xx.s" file, to
+ * configure the system clock before to branch to main program.
+ *
+ * 3. If the system clock source selected by user fails to startup, the SystemInit()
+ * function will do nothing and HSI still used as system clock source. User can
+ * add some code to deal with this issue inside the SetSysClock() function.
+ *
+ * 4. The default value of HSE crystal is set to 8 MHz (or 25 MHz, depedning on
+ * the product used), refer to "HSE_VALUE" define in "stm32f10x.h" file.
+ * When HSE is used as system clock source, directly or through PLL, and you
+ * are using different crystal you have to adapt the HSE value to your own
+ * configuration.
+ *
+ ******************************************************************************
+ * @attention
+ *
+ *